Timer IRQ only fires once.

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
suthers
Member
Member
Posts: 672
Joined: Tue Feb 20, 2007 3:00 pm
Location: London UK
Contact:

Timer IRQ only fires once.

Post 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
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Re: Timer IRQ only fires once.

Post 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
elkvis
Posts: 5
Joined: Sun Apr 13, 2008 4:40 pm
Location: River Falls, WI, USA

Re: Timer IRQ only fires once.

Post 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.
User avatar
TNick
Posts: 18
Joined: Fri May 09, 2008 7:50 am
Location: Brasov, Romania

Re: Timer IRQ only fires once.

Post 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:
User avatar
suthers
Member
Member
Posts: 672
Joined: Tue Feb 20, 2007 3:00 pm
Location: London UK
Contact:

Re: Timer IRQ only fires once.

Post 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
Post Reply