Menu

Multiple Interrupts Problem

Help
joe rocci
2009-08-03
2013-05-30
  • joe rocci

    joe rocci - 2009-08-03

    I'm developing a program that uses interrupts from Timer0, Timer1, and the PortB INT pin. Timer0 and Timer1 interrupts are sort of synchronous to each other, as the Timer 1 interrupt can only happen after the Timer 0 interrupt sets up the right conditions. The Timer0 and Timer1 interrupts co-exist peacefully and don't seem to interfere with each other. However, the INT interrupt is asynchronous to the other two interrupts, and can happen at any time.

    Nothing happens in the very tight main loop until a flag variable indicates that Timer0 and Timer 1 have done their thing, at which point the main program code runs once and waits for the next  TMR0/TMR1 interrupt indication. The only thing that interrupts the body of the main program is the INT interrupt.

    The program works just fine when only Timer0 and Timer1 interrupts are running, but the asynchronous INT interrupt sometimes crashes the whole system. I'm not sure if the problem is the INT interrupt per-se (one line of code) , or something to do with the fact that this interrupt is asynchronous with everything else the system is doing and can happen at any time. I've carefully checked to make sure no other interrupts are enabled, so I'm pretty sure it's something related to the active interrupts.

    I've spent the better part of a week trying all sorts of -process-of-elimination tests to resolve this, but it's still eluding me. My question: Are there any known issues with interrupts in GCBasic that I should be aware of, things like certain functions that shouldn't be interrupted (such as EEPROM), timing issues related to possible simultaneous interrupts, etc?

    Thanks
    Joe

     
    • kent_twt4

      kent_twt4 - 2009-08-03

      Have you tried disabling interrupts when in the PortB INT sub, by using INTOff and INTOn on entry/exit?  Or vice-versa in the Timer0 and Timer1 int subs.  I think some of the 18f's have a priority interrupt, which may be useful?, have not tried personally.

       
      • joe rocci

        joe rocci - 2009-08-03

        According to Microchip:

        "When an interrupt is responded to, the GIE bit is cleared to disable any further interrupt, ...."

        and:

        "The “return from interrupt” instruction, RETFIE, exits the interrupt routine, as well as sets the IE bit, which re-enables interrupts.

        So I don't see the need to do any further interrupt disabling within the interrupt handler. Am I missing something?

        Joe

         
      • joe rocci

        joe rocci - 2009-08-03

        According to Microchip:

        "When an interrupt is responded to, the GIE bit is cleared to disable any further interrupt, ...."

        and:

        "The “return from interrupt” instruction, RETFIE, exits the interrupt routine, as well as sets the IE bit, which re-enables interrupts.

        So I don't see the need to do any further interrupt disabling within the interrupt handler. Am I missing something?

        Joe

         
    • kent_twt4

      kent_twt4 - 2009-08-03

      Well, you are right on the interrupt dsiable/enable.

      I am sure its been thought of, but one could poll the input pin, rather that use an interrupt.  This  doesn't answer the question, but if you are in a jam.

      Doing serial comms like RS232 , one wire, or I2C,  it seems conceivable that you could hang the system in an unexpected state.  That could be a reason to use the watchdog timer for a reset.

       
    • Nobody/Anonymous

      I finally updated to using the latest version.  I believe there is still a problem with the interrupt handler, at least for the 12F that I am using.  You can search the forums for an earlier post.  The newest code is much improved!  The sysw and sysstatus are now allocated in the upper shared bank memory as it must.  Prior versions I had to manually edit this.  But I believe there is still one problem left.  The SysIntOffCount variable is not set correctly, if just prior to the interrupt a bank other than 0 was selected.   I have not analyzed what happens if the variable is set incorrectly.  There is a bank select in the interupt handler next, so everything after is ok.

      Interrupt
      ;Save Context
          movwf    SysW
          swapf    STATUS,W
          movwf    SysSTATUS
          incf    SysIntOffCount,F
          banksel    STATUS

      The correct code should be:
      'Interrupt handler:
      ;Save Context
          movwf    SysW
          swapf    STATUS,W
          clrf    STATUS

      The clrf STATUS instruction is missing, as resets to bank 0.  Try adding this and see if your problems are corrected.

       
      • Nobody/Anonymous

        Thanks for the insights on this. I also wondered if it was a problem with context-saving/restoration, or if a bank pointer is wrong somewhere, as the entry/exit code is a bit different than what Im used to. I'll give it a try.

        How did you try your changes? Did you edit the .asm file that GCBasic makes and then re-run the assembler on it? Or did you somehow put some assembly code right in the GCBasic source code?

        Joe

         
    • Nobody/Anonymous

      I use a text search and replace program on the .asm file as part of the compile script.  Then assemble and run in microchip's IDE.

      I made a slight mistake above.  If the clrf STATUS is inserted as shown, the SysSTATUS variable does not need to be in upper memory, only SysW.  Also, as it is depending on where SysIntOffCount is allocated, it can overwrite some random Bank 1 setting.  This can cause all kinds of trouble (thats very hard to discover).

       
      • joe rocci

        joe rocci - 2009-08-04

        Thanks,

        It sounds like it might be better all around if I handle interrupts in my own assembler-based code rather than let GCBasic handle them. Do you agree?

         
    • Nobody/Anonymous

      Hello..

      >The SysIntOffCount variable is not set correctly, if just prior to the interrupt a bank other than 0
      >was selected. I have not analyzed what happens if the variable is set incorrectly.
      >There is a bank select in the interupt handler next, so everything after is ok.

      For what i know, GcBasic only add banksels when needed; i'm not 100% sure, but perhaps you can't see banksels in interrupt routine because there are not variables in other banks than bank0.

      To see if there is a real problem you should compile a program with some variables in bank1...

      Regards.

       
    • Nobody/Anonymous

      I am using GCBasic for my interrupt routines, and except as stated above, they work quite fine.  If you are familiar, it doesn't take long to look the code over after compile to see any obvious issues.  Debug finds the others.

      With the newest versions, GCBasic now handles advanced context saves (and now longer interrupt disables before any advanced math) so you can even use advanced math in your interrupt routines.  Tedious to do that in assembly.  Even though I have wrote lots of assembler in my days, that PIC instruction set it too much of a pain for me.

      GCBasic does not store variables in bank 1 (that I have ever seen).  But the problem lies if you are setting a parameter in bank 1 for some hardware on the chip, and the interrupt hits.  This is the need for the clrf STATUS instruction.

       
    • Santiago

      Santiago - 2009-08-07

      >GCBasic does not store variables in bank 1 (that I have ever seen).

      If you have just a few variables then all will fit in Bank0, but when you have many then they will be placed in Bank1, 2...

      >But the problem lies if you are setting a parameter in bank 1 for some hardware on the chip,
      >and the interrupt hits. This is the need for the clrf STATUS instruction. 

      Ok... now i see.

      What i did is editing the gcbaic.bas file and recompile it, now i have this interrupt context save:

      ;Save Context
          movwf    SysW
          swapf    STATUS,W
          clrf    STATUS
          movwf    SysSTATUS
          swapf    PCLATH,W
          clrf    PCLATH
          movwf    AASysPCLATH
          swapf    FSR,W
          movwf    AASysFSR
          incf    AASysIntOffCount,F

      What do you think?
      The "AASys..." variable names is to be sure (not 100% but enought) that this variables will be placed into Bank0.

      I edited gcbasic.bas (lines 891-... in my version) and added some lines, here is what i have now:

              'Add context save code

              CurrLine = SubStart

              AddVar "SysW", "BYTE", 1, 0, "REAL", ""

              AddVar "SysSTATUS", "BYTE", 1, 0, "REAL", ""
              AddVar "AASysPCLATH", "BYTE", 1, 0, "REAL", "" ' ..............Variable added
              AddVar "AASysFSR", "BYTE", 1, 0, "REAL", "" '..................Variable added

              AddVar "AASysIntOffCount", "BYTE", 1, 0, "REAL", "" '...........Name changed to AASys...

              If ChipFamily = 14 Then

                  'Will need to put SysW, SysSTATUS into shared bank

                  CurrLine = StringListInsert(CurrLine, ";Save Context")

                  CurrLine = StringListInsert(CurrLine, " movwf SysW")

                  CurrLine = StringListInsert(CurrLine, " swapf STATUS,W")
                  CurrLine = StringListInsert(CurrLine, " clrf STATUS") '...........    Line added

                  CurrLine = StringListInsert(CurrLine, " movwf SysSTATUS")
                  CurrLine = StringListInsert(CurrLine, " swapf PCLATH,W") '              Line added
                  CurrLine = StringListInsert(CurrLine, " clrf PCLATH") '                 Line added

                  CurrLine = StringListInsert(CurrLine, " movwf AASysPCLATH") '            Line added
                  CurrLine = StringListInsert(CurrLine, " swapf FSR,W") '                 Line aded

                  CurrLine = StringListInsert(CurrLine, " movwf AASysFSR") '              Line added

                  CurrLine = StringListInsert(CurrLine, " incf AASysIntOffCount,F") '       Name changed

      Of course the correspondient lines should be added to restore contex.

       
    • Hugh Considine

      Hugh Considine - 2009-08-08

      Have uploaded a new update, which should save FSR correctly.

      Joe, I'd recommend writing interrupts in GCBASIC, I do. The number of interrupt related bugs is dropping, and it should be usable.

       
    • Nobody/Anonymous

      Hugh,

      I downloaded and installed the 8/9 update, but the context save in the compiled code looks unchanged - no FSR or PCLATH save.

      Joe

       
    • Hugh Considine

      Hugh Considine - 2009-08-09

      What's in the interrupt, an array, a string, or a hard coded reference to FSR? GCBASIC won't save FSR if it's not changed in the interrupt, and it won't save PCLATH unless there's a pagesel.

       
    • Santiago

      Santiago - 2009-08-09

      Ok.. i have tried it and works great!!

      In my first try it didn't work because i used an "alias" to point a variable to FSR, i ussually do this to decrement the number of variables used in functions and to have a shorter code.
      For example i was doing it in this function:

      Function Peek (MemAdr As Word)

                  Dim MemAdr As Word Alias SysCalcTempA_H, FSR '...<<-----------HERE

                  Dim Peek As byte Alias SysCalcTempX

                  SET STATUS.IRP OFF

                  if SysCalcTempA_H.0 ON then SET STATUS.IRP ON

                  PEEK = INDF

      End function

      The memadress is parsed to FSR before the function is called.
      This way i don't need to create 2 or 3 new variables in each function i use, and also save some instructions.

      When i have a lot of variables and Bank1 1 is in use i also have a lot of banksels that bloats the code and slow speed (i think banksels take 2 instructions in some pics) then keeping everything in Bank0 is a good thing for some pics when speed is needed.

      I used this function inside interrupts and FSR save didn't work because  i used FSR "aliased", but using FSR directly works great.

      I think now interrupts can work very well.

      I like that System variables saving on interrupts only occur when needed... good Job!!

      Regards... and thanks again .. :)

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.