gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Beginners > Interrupt Service Routine

#56258 - Tomik - Fri Oct 07, 2005 2:01 pm

Hi Dudes ;)

I got a problem with the ISR ! Can somebody help me with that ?
Where do I have to put it in the prog.
I just want to control for sampling rate and filtering stuff. therefore i need a timer interrupt. i did this, but works not serious.
Code:

main
{
  //Timer Interrupt 
  while
  {
    //bla bla
  }
}


I need a ISR which stops the main whenever it comes ! So do you have a idea for me ??

Thanks, Thomas

#56514 - quickcup - Sun Oct 09, 2005 7:06 am

Code:


my_irq() {

    if (timer interrupt) {
       do timer interrupt stuff
    }

}

interrupt_handler = my_irq

main() {
   turn on global interrupts
   turn on timer interrupt
   turn on timer

   do stuff while waiting to be interrupted {
      ...
   }
}



Well that's the pseudo code anyway. I'll see if I can find the actual code.

#56637 - Tomik - Mon Oct 10, 2005 8:28 am

Thats what I want. please search the source code for me !!

Thanks, Thomas

#56740 - crossraleigh - Tue Oct 11, 2005 12:12 am

It looks like quickcup is describing the way to do it in DevKitAdvance. If you are using devkitARM, libgba will handle the dirty work for you. Documentation is available. Here is an (untested) example:

Code:
void my_interrupt_function()
{
   // ...
}

int main()
{
   InitInterrupt();
   SetInterrupt(Int_Timer0, my_interrupt_function);
   EnableInterrupt(Int_Timer0);
   REG_IME = 1;

   for(;;);

   return 0;
}

_________________
My world is black and white, but if I blink fast enough, I see it in grayscale.

#57233 - Tomik - Fri Oct 14, 2005 1:42 pm

why doesn?t this jump to my ISR ??
Code:
u32 ISR(int *yArr);            // Interrupt Service Routine

int main(void)
{   SetMode(MODE_4 | BG2_ENABLE );      // set mode 4
   
   REG_IME = 0x00;                  // disable all interrupts

   REG_INTERRUPT = (u32)ISR(yArr);      // point Function (ISR) to Interrupt register   

   REG_IE = 0x60;

   REG_TM2D   = 0xFFFF-0x170;         // 368=0x170 ticks is 20ms = 44.5 Hz for xValue shifting
   REG_TM2CNT = TM_ON | TM_FREQ_1024;   // Timer enable | 1024 cycle timer (16.xxMHz) -> 61.04us / 16.384kHz
   REG_TM3CNT = TM_ON | TM_CASCADE;
   EraseScreen();
   Logo();
   WaitForVblank();
   Flip();
   Sleep(100);      
REG_IME = 0x01;                  // enable all interrupts

   while(1);


u32 ISR(int *yArr)
{
   u16 xAxisShift=REG_TM3D;

   if(REG_TM3D != xAxisShift)
   { // do something   
   xAxisShift= REG_TM3D;
   }
   return(0);
}

#57241 - Cearn - Fri Oct 14, 2005 2:37 pm

Tomik wrote:
why doesn?t this jump to my ISR ??
Code:
u32 ISR(int *yArr);            // Interrupt Service Routine

int main(void)
{   SetMode(MODE_4 | BG2_ENABLE );      // set mode 4
   
   REG_IME = 0x00;                  // disable all interrupts

   REG_INTERRUPT = (u32)ISR(yArr);      // point Function (ISR) to Interrupt register   

   REG_IE = 0x60;

   REG_TM2D   = 0xFFFF-0x170;         // 368=0x170 ticks is 20ms = 44.5 Hz for xValue shifting
   REG_TM2CNT = TM_ON | TM_FREQ_1024;   // Timer enable | 1024 cycle timer (16.xxMHz) -> 61.04us / 16.384kHz
   REG_TM3CNT = TM_ON | TM_CASCADE;
   EraseScreen();
   Logo();
   WaitForVblank();
   Flip();
   Sleep(100);      
REG_IME = 0x01;                  // enable all interrupts

   while(1);


u32 ISR(int *yArr)
{
   u16 xAxisShift=REG_TM3D;

   if(REG_TM3D != xAxisShift)
   { // do something   
   xAxisShift= REG_TM3D;
   }
   return(0);
}


There are many reasons why this won't work

First of all, isrs don't take arguments or return values. While that doesn't
doesn't mean the couldn't run, they wouldn't do what you'd expect them to do.
Secondly, the function that REG_INTERRUPT ( that's 0300:7FFC, right? (or 03FF:FFFC) ) must be ARM code. I suspect that you're using THUMB code for the main file (which you should), so the program would lock up on reaching the isr.
Thirdly, while you set REG_IE to catch interrupts, you also need to set different registers to fire them. For timers, that's REG_TMxCNT, bit 6.
Finally, you also need to acknowledge you've dealt with the interrupt. You do this by setting the appropriate bit in REG_IE while in your isr.

tonc: interrupts, timers.
gbatek: interrupts, timers.

#57600 - Tomik - Mon Oct 17, 2005 7:52 am

Thanks, thats why I put it in Beginners !
I never did something with interrupts ...
... I made everything with the help from www.jharbour.com/gameboy/default.aspx and that says I can handle the ISR as a function in C/C++ !! What do you think ??

Thomas

#57606 - Tomik - Mon Oct 17, 2005 9:55 am

I read the TONC stuff: it says if I have only one interrupt I dont need ASM !! Thats right or what is the diff between:

Code:
main
{
 while(1);
}

ISR{};


and
Code:

main
{
 while(1)
 {
  ISR();
 }
}


So i can make the ISR code in C/C++ ...
... will check the other reasons ! Fire interrupt .. etc

Thomas

#57607 - Cearn - Mon Oct 17, 2005 10:10 am

Technically, you don't need asm for interrupts, no. Not even for multiple interrupts, actually. I think Tetanus on Drugs] uses multiple interrupts in C, but I may be wrong. However, asm will allow faster interrupts, and you don't have to muck with compiler switches to create ARM code for the main isr.

The difference between
Tomik wrote:
Code:
main()
{
 while(1);
}

ISR{};
and
Code:
main()
{
 while(1)
 {
  ISR();
 }
}
is that in the latter, the ISR() function is just part of the main code flow and so it's really an interrupt (it doesn't interrupt anything after all). An interrupt routine is something that happens outside the normal program, to be called by the OS/BIOS/hardware, only only under certain conditions. An interrupt stops the regular program to do something else for a while, and can do so at any time, no matter what the real program is currently doing.

#57609 - Tomik - Mon Oct 17, 2005 10:54 am

that is correct, but in this case there is no other programm !
in the wihle() ist only the ISR !! so if the ISR-Function is not longer as the Interrupt fire... it should be the same function ....

thanks for your help, I?ll check it out ;)

Viele gruesse an unsere niederlaendischen freunde .. aus hamburg, der stadt in der "van der vaart" lebt, super spielt und am samstag die rote karte bekommen hat ...

Thomas