EmbDev.net

Forum: ARM programming with GCC/GNU tools help with interupt


von Sevc D. (sevc)


Rate this post
useful
not useful
Hi all.
I need help with interupt.
My English is poor ,if write right what I mind.
On my project I want use timer interupt.If match register is same like
timer then generate only interupt (no reset timer).But problem is if
interupts generate like Match register 0 and then Match register 1 (low
time after).
if MR0 same like TIMER0 then generate interupt.
I read IR register to read and check at what match register generate
interupt.
example :
MR0 = 100
MR1 = 103
... tiemer .. tic... tac... tic... tac... 99...100 -> generate interupt
(MR0=timer)
then program execute interupt handler and read IR register to detect MR.
program see so interupt generate MR0 and clear interupt,and then execute
user code. but if in this time MR1 same like timer then in IR register
set 1, but I'm still in interupt handler. What happend if exit from
handler of interupt, generate interupt again or not . how can I set to
correct work.
I want, so if generate interupt, I check source, handling it and execute
own code. if in this time is generate other interupt (MR1 match with
tiemr or else) and I'm in handling actual interupt then go exit from
handling and interupt is genrate again.
I need four independent interupt of tiemer.
I thinks so can use timer 0 to set free running, match register
(0,1,2,3) set any value(MR0=100,MR1=150,MR2=300,MR3=400) and wait to
interupt. if timer generate interupt then check source and this is my
solution:
if interupt generate MR0 then MR0=MR0+100 and clear state in IR, and so
on with other MR.
then I can generate with MR0 interupt every ((1/15MHz)*100) of basic
time. and so on.
what do you mind????

regards

von Sevc D. (sevc)


Rate this post
useful
not useful
I'm forget the MCU is LPC2142

von Mhel M. (mhel)


Rate this post
useful
not useful
Hi Sevc,

I am a newbie, so if this does not make sense please disregard.

Maybe it would be easier to create something like this, let say you
setup the timer to interrupt every millisec.

volatile uint32_t HUNDRED_MS;
volatile uint32_t TWO_HUNDRED_MS;
volatile uint32_t THREE_HUNDRED_MS;
volatile uint32_t FOUR_HUNDRED_MS;

Bool 100MS_Flag;
Bool 200MS_Flag;
Bool 300MS_Flag;
Bool 400MS_Flag;

/* timer1 interrupt every 1ms*/
void timer1ISR(void)
{
  ISR_ENTRY();
  if (++HUNDRED_MS >= 100)
    {
      HUNDRED_MS = 0;
      100MS_Flag = TRUE;
      if (++TWO_HUNDRED_MS >= 200)
        {
          TWO_HUNDRED_MS = 0;
          200MS_Flag = TRUE;
          {
            if (++THREE_HUNDRED_MS>=300)
              {
                THREE_HUNDRED_MS = 0;
                300MS_Flag = TRUE;
                if (++FOUR_HUNDRED_MS >= 400)
                  {
                    FOUR_HUNDRED_MS = 0;
                    400MS_Flag = TRUE;
                  }
              }
          }
        }
    }

//  T1IR = 1;                 //clear interrupt
  VICVectAddr = 0x00000000; // clear this interrupt from the VIC
  ISR_EXIT();               // recover registers and return
}


void main(void)
{

HUNDRED_MS = 0;
TWO_HUNDRED_MS = 0;
THREE_HUNDRED_MS = 0;
FOUR_HUNDRED_MS =0;

  for (;;)
    {
      if (100MS_Flag = True)
        {
          //do something 1
          100MS_Flag = False;
        }
      if (200MS_Flag = True)
        {
          //do something 2
          200MS_Flag = False;
        }
      if (300MS_Flag = True)
        {
          //do something 3
          300MS_Flag = False;
        }
      if (400MS_Flag = True)
        {
          //do something 4
          400MS_Flag = False;
        }

    }

}


...just maybe it would help.

von Mhel M. (mhel)


Rate this post
useful
not useful
corrections: signs of newbie showing up ;)

for (;;)
    {
      if (100MS_Flag == True)
        {
          //do something 1
          100MS_Flag = False;
        }
      if (200MS_Flag == True)
        {
          //do something 2
          200MS_Flag = False;
        }
      if (300MS_Flag == True)
        {
          //do something 3
          300MS_Flag = False;
        }
      if (400MS_Flag == True)
        {
          //do something 4
          400MS_Flag = False;
        }

    }

von Sevc D. (sevc)


Rate this post
useful
not useful
Hi.
thanks for your solution but 1ms is very big time for me I need ns.
If I set peripherie clock  1/15Mhz then it's time for me.
But I can't set interupt every 1/15Mhz .
to use MR0..3 to generate interupt is good but I don't know what hapend
if other MR generate interupt in existing interupt.
First time I thinks so set basic time to 1us (timer value 14) but its
too big.
If basic time is big then I must calculate more corection.

regards

von Mhel M. (mhel)


Rate this post
useful
not useful
maybe something like this would work

T1PR = 3; // 100ns assuming ((PCLK=30Mhz) / T1PRvalue) as in systime.h
of WinARM examples
T1MR0 = 1; //interrupt every 100nS
T1MR1 = 2; //interrupt every 200nS
T1MR2 = 3; //interrupt every 300nS
T1MR3 = 4; //interrupt every 400nS
T1MCR = 0x0649; // interrupt on every match but reset counter only in
MR3 match

offcourse interrupt should be cleared everytime it kicks in.

I'm learning this myself, so this is most likely wrong, let's hope
the smarties join in :)

von Sevc D. (sevc)


Rate this post
useful
not useful
Mhel Marcelo wrote:
> maybe something like this would work
>
> T1PR = 3; // 100ns assuming ((PCLK=30Mhz) / T1PRvalue) as in systime.h
> of WinARM examples
> T1MR0 = 1; //interrupt every 100nS
> T1MR1 = 2; //interrupt every 200nS
> T1MR2 = 3; //interrupt every 300nS
> T1MR3 = 4; //interrupt every 400nS
> T1MCR = 0x0649; // interrupt on every match but reset counter only in
> MR3 match
>
> offcourse interrupt should be cleared everytime it kicks in.
>
> I'm learning this myself, so this is most likely wrong, let's hope
> the smarties join in :)

Hi.
your solutinon is good but question is what happend if interupt generate
MR in existing interupt (like MR2) . If I exit from interupt (handle
interupt from MR1) and CPU go to interupt again (detect interupt from
MR2 and handle) or not , .
In AVR its easy. If I'm in interupt (timer or else) clear interupt flag
(first code) and do some user code (still I'm on interupt) and timer
generate interupt again . if exit from interupt then CPU generate
interupt again .

regards.

von Simon E. (fordp)


Rate this post
useful
not useful
To answer the original question.

I suggest you loop round in your ISR handling all match sources that are
relevant.

If a new match source want to Interrupt after you have checked it and
while still in the ISR then the processor will interrupt again.

See that was easy.

The problem you may have however is that the chip may not handle you
interrupts quickly enough, or may not be able to handle the rate of
interrupts you are generating. The third problem is that with all these
interrupts happening there may not be any time left to process your main
loop.

All the best.

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.