Monday, 22 October 2007

Interrupt (IRQ) handling for Timers

Interrupt မွာ ၂ မ်ိဳးရွိပါတယ္။ Hardware IRQ နဲ႔ Software IRQ ပါ။ Hardware မွာ Port IRQs, Key IRQs, Display IRQs ေတြပါၿပီးေတာ့၊ Software မွာ Timer IRQs, DMA IRQs ေတြပါတယ္လို႔ ခြဲလို႔ရပါတယ္။ Hardware, Automation, Machine ေတြကို Accurate Timing နဲ႔ အလုပ္လုပ္ခ်င္တဲ့အခါ သံုးၾကတာပါ။ Embedded Software ေတြမွာ အဓိကသံုးပါတယ္။ Interrupt မွာသံုးတဲ့ Register ေတြကေတာ့ REG_INTERUPT, REG_IME, REG_IE, REG_IF ေတြပါ။
REG_INTERUPT က interrupt handler ပါ။ interrupt ျဖစ္တဲ့အခါ လုပ္လုိက္တဲ့ Action ကို မွတ္တဲ့ register ပါ။
REG_IME က master interrupt ပါ။ Interrupt ေတြကို အဖြင့္အပိတ္ (Enable, Disable) လုပ္ေပးတဲ့ register ပါ။
REG_IE က interrupt enable ပါ။ ဘယ္ interrupt ကို လုပ္မယ္ဆိုတာ သတ္မွတ္ေပးတာပါ။ REG_IME နဲ႔ကြာတဲ့အခ်က္ကေတာ့ က interrupt တစ္ခုခ်င္းစီအတြက္ (Enable, Disable) လုပ္တာပါ။
REG_IF က လက္ရွိေရာက္ေနတဲ့ interrupt ကို စစ္ေဆးတာပါ။ ဥပမာ - Timer0 overflow interrupt ကိုေရာက္သြားၿပီဆိုရင္ REG_IF မွာ Timer0 ရဲ႕ bit pattern ေရာက္သြားပါတယ္။ REG_IE bit pattern နဲ႔ အတူတူပါပဲ။ ေအာက္က နမူနာ program ကိုၾကည့္ရင္ ရွင္းပါလိမ့္မယ္။

//.......................INTERRUPT Routine
void enableTimerInterrupt()
{
REG_IE |= INT_TIMER0; // Enable Timer interrupt detection
REG_TM0CNT |= TIME_IRQ_ENABLE; // Make Timer generate IRQ
}

void interruptHandler(void)
{
REG_IME = 0; //disable interrupts
if(REG_IF==INT_TIMER0)
{
if(stateflag==0){SCLO();stateflag=1;}
else if(stateflag==1){SCHI();stateflag=0;}
}
REG_IF = REG_IF; // Tell GBA that interrupt has been handled
REG_IME = 1; //enable interrupts
}

void setupInterrupts(void)
{
REG_IME = 0x0; //disable interrupts
REG_INTERUPT = (u32)interruptHandler; //set int handler
enableTimerInterrupt();
REG_IME = 0x1; //enable interrupts
}

setupInterrupt() ဆိုတဲ့ function ကိုေခၚၿပီး သံုးရပါတယ္။

No comments:

Post a Comment