timer

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.
petrusss

timer

Post by petrusss »

I'm having some problems with the timer, I can't make it launch my function for IRQ0.
If I outb(0x40, 0x34) the system slows down, but nothing else.
Should the timer start firing IRQ0 when I've unmasked IRQ0?
proxy

Re:timer

Post by proxy »

silly question..

did you enable interrupts via a sti op?

proxy
petrusss

Re:timer

Post by petrusss »

yup, keyboard and floppy is working correctly.

Code: Select all

   outb(0x43, 0x10);
   outb(0x40, 0x4);
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:timer

Post by Pype.Clicker »

so, you're setting the clock to "mode 0 (interrupt when count reached), binary 16 bits, read lsb only" and then send "4" as the LSB counter, is it what you want to do ?

comparing mode 0 (which sets the output high until PIT reprogrammed) and mode 2 (normal operating mode for the system clock: output goes low for one period and then high again, which probably means the IRQ will be raised on the falling edge of the output line), there are chance the cpu is waiting for the PIT going 'low" again to trigger the IRQ, and the PIT is waiting the CPU to reprogram it ...

in other words, you should better use the "programmable one-shot" or the "rate generator" mode for IRQ0 control ... other modes does not fit what the PIC/CPU expect and will fail to issue IRQs, imho ...

just in case you don't have it already:
http://www.nondot.org/sabre/os/files/MiscHW/PIT.txt
petrusss

Re:timer

Post by petrusss »

I've tried that now, it doesn't fire IRQ0...
I read from 0x40 in a loop and I can see it changes..
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:timer

Post by Pype.Clicker »

that's some piece of good news... however it's not sufficient to get timer irq fired. Can you show me the updated "clock init" code ? and possibly the irq (un)masking code aswell ?

many people make the error of clearing the old mask when they add a new int.

Code: Select all

    outb(PICMASTER_MASK,1<<irq);
is not enough for it will leave you with 00001000 (if irq==4, for instance) instead of xxxx1xxx (where 'x' means 'untouched').

Code: Select all

    old_mask=inb(PICMASTER_MASK);
    outb(PICMASTER_MASK,old_mask|(1<<irq));
usually do the trick ...
petrusss

Re:timer

Post by petrusss »

With your unmasker, nothing worked, not even the keyboard.

Code: Select all

void InitializeTimer() {
   AddInt(0x20, Timer_stub, 0);
   unmaskIRQ(TIMER);

   outb(0x43, 0x12); 
   outb(0x40, 0x4);
}
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:timer

Post by Pype.Clicker »

that was pseudo-code to illustrate a common mistake, not ready-to-put-in-your-kernel(tm) code ...
Maybe you could try to print the content of the master PIC's mask at the end of each unmask(..) call to make sure things are ok ...

what do your unmask() code look like, btw ?
petrusss

Re:timer

Post by petrusss »

Code: Select all

      _irq = _irq & (1 << _irq);

      uint8 IRQMask = inb(MASTERDATA);
      outb(MASTERDATA, IRQMask & (1 << _irq));
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:timer

Post by Pype.Clicker »

okay, i see the error i made: when a bit is "1" in the mask, the interrupt is masked and when it's "0" irq is enabled ...

so you must not do "irq = irq & (1<<no)" but rather "irq = irq & ~(1<<no)" to unmask no ...
petrusss

Re:timer

Post by petrusss »

Thanks alot!
The timer is working ;)
User avatar
Neo
Member
Member
Posts: 842
Joined: Wed Oct 18, 2006 9:01 am

Re:timer

Post by Neo »

This is with ref to the Intel 8253/8254 timers. These PITs provide us with 3 timers,can we use all 3 at the same time? if so how do we tell which timer is firing when a IRQ is generated? also can i use one timer exclusively for the system time,one for process mngmt etc? and also are there any other issues to be considered here?
Any info or suggestions appreciated.
Only Human
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:timer

Post by Pype.Clicker »

all of the 3 timer/counters of the chip can be programmed on a legacy 8086 motherboard (however, reprogramming the one that control memory refresh is hazardous at best), but only the output of the first three timers is hardwired to the IRQ0 line of the PIC.

the third one is bound to the PC-speaker through a NAND gate controlled by SomeOtherChip (8042 iirc). The 3rd clock controls the frequency of the tone played by the speaker while the other signal to the NAND gate tells whether the speaker is muted or not ...
User avatar
Neo
Member
Member
Posts: 842
Joined: Wed Oct 18, 2006 9:01 am

Re:timer

Post by Neo »

so how do i use all 3 at the same time and determine which is interrupting when i get a IRQ ? also can i reprog the memory refresh counter will it affect memory access etc?
Only Human
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:timer

Post by Pype.Clicker »

you *cannot* get an IRQ for another of the 2 counters for their output are *not* connected to any kind of interrupt controllers.

On a modern system, whatever you do with the memory refresh counter is likely to have no effect at all. Using the 8253 (iirc) for mem refreshes was true on old systems, but the refresh logic is probably very different nowadays ...

Keep in mind that we're dealing with chipsets that emulate ol' good 82xx series, no longer with the 82xx themselves ...
Post Reply