Page 1 of 1

why PIT execute it only once?

Posted: Wed Oct 22, 2008 4:40 pm
by posman
Hi. I was trying to initialize the PIT and make the interrupt write a counter on screen every time. I (think) it was successfully initialized because it actually prints the counter on screen. The problem is that it's only written once. Well, that's what I think, maybe the counter it's not being incremented.

Here is the code for the timer initialization and interrupt routine

Code: Select all

#define PIC1 0x20
#define TIMER_CONTROL 0x43
#define TIMER_DATA 0x40
#define TIMER_INIT 0x36

volatile unsigned int cont_pulsos = 0;

void timer_install(unsigned int frec) {
	unsigned int divisor = 1193180/frec;

	outb(TIMER_CONTROL,TIMER_INIT);
	outb(TIMER_DATA,divisor & 0xFF);
	outb(TIMER_DATA,(divisor>>8));
	//unmask IRQ0, is this necessary? I haven't modified this register before
	outb(PIC1+1,(inb(PIC1+1)&0xFE));
}
void int_timer() {
	cont_pulsos++;
	printHex(cont_pulsos);
	//send EOI
	outb(0x20,0x20);
}
This is the main program:

Code: Select all

void init() {
	idt_install();
	PIC_remap();
	timer_install(100);
	sti();

	char wheel[] = {'\\','|','/','-'};
	int i = 0;

	for (;;) {
		__asm__ ("movb %%al, 0xb8000+160*20"::"a"(wheel[i]));
		if (i == sizeof wheel)
			i = 0;
		else
			++i;
	}
}
IDT is right and also PIC is remaped correctly. If I don't remap PIC, I get exception 8 (I'm already handling all exceptions).
As I said before, maybe the counter it's not incrementing :oops:

Hope you can help me

Re: why PIT execute it only once?

Posted: Wed Oct 22, 2008 5:01 pm
by gmoney
do you have a irq handler and if so is the timer driver loaded into the handler. from the code you posted the variable is incremented but cant help you out to much till you post your handler and where the timer driver is loaded.

Re: why PIT execute it only once?

Posted: Wed Oct 22, 2008 6:21 pm
by posman
what do you mean with timer driver?

I remap IRQs to int 0x20 (PIC1) and 0x28 (PIC2). Inside idt_install I have this:

Code: Select all

addIDTEntry(0x20,&int_timer);
int_timer is the function that is executed on each interrupt

Re: why PIT execute it only once?

Posted: Wed Oct 22, 2008 7:04 pm
by gmoney
have you tried cli at the beginning of the "init()" function, stopping all interupts install the idt, gdt, timer and the reenable all interupts

invalid initialization?

Posted: Thu Oct 23, 2008 2:24 pm
by ivannz
Hello,

Why do you initialise zero'th counter to a square wave generator mode?

AFAIK, it should be either "simple rate generator" (mode 2) or "zero detection interrupt" mode (mode 0), but in the latter case you have to reprogram timer counter every interrupt.

36h = 00 11 011 0 = zero'th counter (00), read/write LSB then MSB of counter (11), MODE 3 (011), binary (0)

try to use this command byte: 34h

34h = 00 11 010 0 = zero'th counter (00), read/write LSB then MSB of counter (11), MODE 2 (010), binary (0)

Cheers
^_^

Re: why PIT execute it only once?

Posted: Thu Oct 23, 2008 4:54 pm
by posman
I got this part of the code from other site. I'm also wondering why to use that mode.

But I've solved the problem. The problem was that there wasn't an iret anywhere in the code. :oops: #-o

But I'll test with the other modes too

Thank you all

Re: why PIT execute it only once?

Posted: Thu Oct 23, 2008 7:16 pm
by cr2
define cont_pulsos as a "static volatile unsigned int"

you might also want a stdint.h file header...