Page 1 of 1

Timer IRQ only fires once.

Posted: Tue Jun 24, 2008 10:25 am
by suthers
Ok, this is weird, one I've setup my timer IRQ, it only ever fires once...
I've checked everything I can think of, I've passed the correct divisor to the pit, interrupts are enabled, I've synced the timer to real time in bochs...
I've tried everything that I can think of, but I still can't figure it out...
Here's the code I use to adjust the PIT frequency:

Code: Select all

void adjust_timer(int hz)
{
    int div = 1193180 / hz;       
    outportb(0x43, 0x36);             
    outportb(0x40, div & 0xFF);   
    outportb(0x40, div >> 8);     
    current_pit_frequency = hz;
    return;
};
It's seams correct to me...
In main I pass 1193180 to this function so that the PIT fire once a second.... (I've tried a few other values to just in case....)
And here is my handler code:

Code: Select all

void timer_handler()
{
    ticks++;
    k_printf("\nTimer irq called", 0x07);
    if ((ticks % (1193180 / current_pit_frequency)) == 0)
    {
        k_printf("\nOne second has passed", 0x04);
    };
};
Which again seems correct, if I pass anything else but 1193180 as pic frequency I only get the "Timer irq called" message, meaning it works, but it's only ever called once... Also if I pass 1193180 as PIT frequency, I get both messages, so it works fine...
I've checked everything that I can think of...., I can't think of anything.
Any suggestions as to what's wrong?
Thanks in advance,

Jules

Re: Timer IRQ only fires once.

Posted: Tue Jun 24, 2008 10:32 am
by JamesM
Hi,

Passing 1193180 to that function will cause it to try and fire at 1193180Hz - that is, 1193180 times per second.

You want to pass the value "1" to it, to fire every second (but note that the PIT can't divide that far! the divisor must fit in 16 bits, so the minimum value it can interrupt at is 18.2Hz.

Are you sure you're ACKing the PIC? (sending an EOI)

Cheers,

James

Re: Timer IRQ only fires once.

Posted: Tue Jun 24, 2008 10:34 am
by elkvis
I'd suggest you check your actual IRQ handler (the one called from the IDT) and make sure that at the end of it you send the proper code to the PIC to tell it to continue to process interrupts. if you don't know what I'm talking about, look in the interrupts section of the wiki.

Re: Timer IRQ only fires once.

Posted: Tue Jun 24, 2008 10:36 am
by TNick
Do you acknowledge the IRQ?
Each IRQ needs to be acknowledged to the PIC manually. You need to have

outb(0x20,0x20)

within any master handler and any

outb(0x20,0x20); outb(0xa0,0x20);

within any slave handler.
from here.

Nick

[edit]Some other replys while posting... :lol:

Re: Timer IRQ only fires once.

Posted: Tue Jun 24, 2008 10:56 am
by suthers
Sorry forgot to send EOI :oops: :oops: :oops:
Sorry EXTREMELY stupid question, completely forgot about the EOI.
Sorry for wasting your time (and mine) :(
Thanks,

Jules