Forum - MCS Electronics

 

FAQFAQ SearchSearch RegisterRegister Log inLog in

INT0 issue

 
Post new topic   Reply to topic    www.mcselec.com Forum Index -> BASCOM-AVR
View previous topic :: View next topic  
Author Message
techknight

Bascom Member



Joined: 21 Apr 2008
Posts: 231

usa.gif
PostPosted: Sat Mar 05, 2016 11:08 pm    Post subject: INT0 issue Reply with quote

is there a built in function to BASCOM-AVR to turn off INT0 while inside INT0's subroutine? Disable INT0 doesnt work...

If something inside the interrupt hangs in the event of a failure, the INT0 will still fire. Even though I tried Disable Interrupts, and Disable INT0 in the ISR.

But the problem comes into play when the routine inside the ISR does finally finish after a failure mode, itll trip the INT0 again instead of finishing the existing subroutine. So as per the Stack, it will keep going back to that locked subroutine until you finally reset the device.

any ideas?

(BASCOM-AVR version : 2.0.7.8 )
Back to top
View user's profile
AdrianJ

Bascom Expert



Joined: 16 Jan 2006
Posts: 2483
Location: Queensland

australia.gif
PostPosted: Sun Mar 06, 2016 12:09 am    Post subject: Reply with quote

Its not really a Bascom problem.

In an AVR, the appropriate IRQ flag is set when the interrupt happens, regardless of whether the IRQ ( or indeed global interrupts ) are enabled or not. All the interrupt enable does is let the state of the IRQ flag pass through to the system which allows the procesor to jump to the interrupt vector. In effect there are a pair of registers, one containing the interrupt flags, and one containing the interrupt enables. Only when both of these, and the global interrupt enable, are set to 1 does the interrupt trigger the processor to jump to the interrupt vector.

Once in any IRQ, all other interrupts are disabled ( by the global interrupt disable ), so unless you explicitly re-enable that, no interrupt can happen inside another interrupt. So disabling interrupts inside an interrupt has no effect, and is not necessary. And the AVR also clears the set interrupt flag automatically before it gets to the IRQ routine. BUT if the interrupt flag is set again while inside the IRQ, immediately on exit from the IRQ routine, that interrupt is passed to the processor, and it jumps back into the IRQ again.

However, what you can do is explicitly clear the offending interrupt flag when within the interrupt ( or indeed anywhere you like ) then that interrupt will be lost - at least until the flag is set again.

Its not intuitive, but to clear an interrupt flag in an AVR, you must write a 1 to the correct bit location in the relevant interrupt register.

And of course it also helps if you write your interrupt routine so that it can always exit without hanging up. This goes with the general design recommendation that you dont try to do complex code in an interrupt, just set flags, or advance counters, or whatever, and do the main part of the processing outside the IRQ. In particular, if you have some sort of wait state in the IRQ, and your external IRQ happens faster than the wait time, then you will always get the effect you see. Its up to you to handle the IRQs faster than they come in, under all possible conditions.

_________________
Adrian Jansen
Computer language is a framework for creativity
Back to top
View user's profile Visit poster's website
techknight

Bascom Member



Joined: 21 Apr 2008
Posts: 231

usa.gif
PostPosted: Sun Mar 06, 2016 1:04 am    Post subject: Reply with quote

Unfortunately, I cant prevent INT0 from ever hanging up, at least not without using the watchdog.

I am using the interrupt to read a magnetic stripe card, using the build in function: ReadMagCard

Problem is, its a blocking function. So, if there was an error or nefarious card swipe, it hangs in the INT0 routine FOREVER.

You can swipe it again, and it will clear, but it goes right back to the previous interrupt. I dunno why that is.

If I can prevent MagCardStripe from ever hanging/blocking a program with maybe some sort of built-in timeout function, the problem wouldnt exist.
Back to top
View user's profile
EDC

Bascom Expert



Joined: 26 Mar 2014
Posts: 971

poland.gif
PostPosted: Sun Mar 06, 2016 11:41 am    Post subject: Reply with quote

GETRC5() is also function that can slow down code if is called in main loop frequently. So not bad idea, I think, is to connect IR receiver into external Interrupt pin.
But if You comment out "Gifr.intf0 = 1" then LCD always show you 255 255 at the end. This because ISR will be started again, Get_remote flag will be set but remote don`t transmit anymore and 255 255 is the final result.
Code:
$regfile = "m32def.dat"
$crystal = 8000000
$hwstack = 64
$swstack = 32
$framesize = 64

Config Int0 = Falling : Enable Int0 : On Int0 Int0_isr

Config Rc5 = Pind.2 , Wait = 2000  ' Pind.2 is also INT0 pin

Dim Get_remote As Byte , Address As Byte , Command As Byte



Enable Interrupts

Do

    If Get_remote = 1 Then
        Get_remote = 0

        Getrc5(Address , Command)


        Locate 1 , 1 :
         If Address < 100 Then Lcd "0" : If Address < 10 Then Lcd "0" : Lcd Address
        Locate 1 , 5
         If Command < 100 Then Lcd "0" : If Command < 10 Then Lcd "0" : Lcd Command


     'try comment this out Wink
     Gifr.intf0 = 1                                         'clear flag that Interrupt should be serviced
      Enable Int0
    End If

Loop
End

Int0_isr:
 Disable Int0
  Get_remote = 1                                            'set flag only
Return


If you have "long" main loop then you can check "Get_remote" flag in many places in your code but this will be always outside the interrupt routine.
Back to top
View user's profile Visit poster's website
AdrianJ

Bascom Expert



Joined: 16 Jan 2006
Posts: 2483
Location: Queensland

australia.gif
PostPosted: Sun Mar 06, 2016 10:50 pm    Post subject: Reply with quote

I dont see anywhere that the ReadMagCard function uses interrupts, so I presume you are doing this externally. But you dont need to, just put the GetMagCard routine somewhere in the main loop, and read it there. Of course you must ensure your main loop is reasonably short, so you get an acceptable response, but even 1 sec should normally be ok for a human-controlled system.

Of course that does not prevent the GetMagCard routine itself from blocking, but then at least you are in the main loop, and can recover a bit easier. eg a timer set to timeout and generate an interrupt, or indeed the watchdog.

Even if you wanted to persist with using INT0, just set the INT0 ISR to set a flag, like InitMagRead = 1, and then in the main loop, read the flag, and do the ReadMagCard there. Dont forget to clear the flag in that routine as well.

_________________
Adrian Jansen
Computer language is a framework for creativity
Back to top
View user's profile Visit poster's website
laborratte

Bascom Expert



Joined: 27 Jul 2005
Posts: 299
Location: Berlin

germany.gif
PostPosted: Mon Mar 07, 2016 2:29 pm    Post subject: Reply with quote

Question: Why is the routine blocking? I've looked into the code and the routine assumes that the card reader is delivering the correct amount of bits (and clk pulses) when tranferring data. If there is an error (i.e. for electrical reasons), only a change of the routine could help (which would be possible).
But IMHO you have problems with the cs line. I could imagine that the line is connected directly to the switch which is detecting the card, and therefore bouncing could happen. Now you are in the common INT0-bounce-problem.

So try Adrian's first suggestion and clear the flag - when exiting the isr! My suggestion is something like:
Code:

Int_isr:
   '(...) whatever to do
   Readmagcard Ar(1) , B , 5   'read the data (of course, use your variables)
   '(...) whatever to do
   waitms 25 'bouncetime
   EIFR.INT0 = 1  'clear the interrupt flag (check the registername of your chip)
return
 
Back to top
View user's profile
Display posts from previous:   
Post new topic   Reply to topic    www.mcselec.com Forum Index -> BASCOM-AVR All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
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 vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum