PIT fast?

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

PIT fast?

Post by Ryu »

Hellos,

I've been doing a lot of testing with the PIT lately to get the most accuracy I can get off the chip. However what bothers me and confuses me is after reading PIT counter, that shouldn't be interrupted in any way and continously counting gives me overall being fast to its frequency. I use counter 2, which I believe nothing but the system speaker is hardwired to it, but it has nevered been enabled.

My code to read the counter looks like this:

Code: Select all

;==================================================================
CWR            equ         BYTE   ; Control Word Register
;==================================================================
CWR_BCD         equ      00000001b   ; binary coded decimal counter
CWR_MODE0      equ      00000000b   ; interrupt on terminal count
CWR_MODE1      equ      00000010b   ; hardware retriggable one-shot
CWR_MODE2      equ      00000100b   ; square wave
CWR_MODE3      equ      00000110b   ; rate generator
CWR_MODE4      equ      00001000b   ; software triggered strobe
CWR_MODE5      equ      00001010b   ; hardware triggered strobe (retriggerable)
CWR_RWLOBYTE   equ      00010000b   ; read/write least signficant byte only
CWR_RWHIBYTE   equ      00100000b   ; read/write most signficant byte only
CWR_RWLOHIGH   equ      00110000b   ; read/write least signficant then most signficant
CWR_COUNTER0   equ      00000000b   ; select counter 0
CWR_COUNTER1   equ      01000000b   ; select counter 1
CWR_COUNTER2   equ      10000000b   ; select counter 2
CWR_LATCH      equ      00000000b   ; latches counter
;-----------------------------------------------------
   mov      ebx, ds:[swSystemPeCounter]
   mov      al, CWR_COUNTER2 OR CWR_LATCH

   out      43h, al
   in      al, 42h         ; counter-2 read LSB
;   sub      bl, al
   mov      cl, al
   in      al, 42h         ; counter-2 read MSB
;   sbb      bh, al
   mov      ch, al


   xor      edx, edx
   mov      ds:[swSystemPeCounter], ecx

   sub      bx, cx         ; this algorithm subtracts a clock each wrap
   sbb      bx, dx         ; around, which means OUT was high. This has no
                     ; relevant strings with OUT, however it attempts to
                     ; keep the correct clocks as it seems to be fast.
                     ; ( note: I'm totally confused why clocks are fast
                     ; and not slow)

   add      ds:[swSystemLoCounter], ebx      ; update system counter
   adc      ds:[swSystemHiCounter], edx
This is in my interrupt routine for IRQ-0 as the resolution to update system counter. For counter-2 which is in mode 2, the LSB=MSB=0 (1000h) and goes high OUT when counter-2 goes to 1. Therefore simply subtracting current counter with previous counter should give us the number of PIT clocks. Because counter-2's clocks should not be interrupted in anyway this should be pretty damn precise.

But the only question is am I latching the counter register correctly? Which is the only thing I can come up with that is making this a bit fast. On the other hand this may be RTC, as its roughly 100ms ahead every 6 hrs comparing it with RTC without the wrap around decrement code (with the wrap around code it is still fast).

In the 8254 datasheet, it shows in the driagram that it shouldn't loose counts when OUT is high, but only when GATE is high, but GATE is never touched, and I'm not even looking for a reason for lost clocks, but why is clocks ahead.

Does anyone know why this is?, could this be RTC is not accurate, or could this be my latch is uncorrectly implemented? Or should I raise my white flag?
mystran

Re:PIT fast?

Post by mystran »

You can safely assume that neither the PIT or the RTC are fully accurate

If you want accurate times, syncronize with NTP, or install a calibrated timer.. or something.
Kemp

Re:PIT fast?

Post by Kemp »

its roughly 100ms ahead every 6 hrs
I'd personally settle for that sort of accuracy, I think it would take a quite exotic purpose for this OS in order for that sort of error to be a problem. Also, if the machine is connected to the net then (when your OS is sufficiently far developed) you can sync with an NTP server somewhere at least once a day (after a whole day of that amount of error you'd be less than half a second out).
Bob the Avenger

Re:PIT fast?

Post by Bob the Avenger »

100ms every 6hours is very accurate for the PIT, what rate have you set the timer for?

i really should test to see how accurate mine is, its on my todo list right after revision :P
mystran

Re:PIT fast?

Post by mystran »

Kemp wrote: you can sync with an NTP server somewhere at least once a day
Or you can just sync continuously, like you are supposed to do, so that you can estimate and average latency to server and such.

My Linux-box's NTP currently gives an estimated error of 16us. That's pretty bad, but the system was recently booted, so I guess that's acceptable. ;)
Bob the Avenger

Re:PIT fast?

Post by Bob the Avenger »

according to my 'calculations' my PIT setup will loose 1sec or 13millisec every 24hrs :(

and now back to avoiding revision, failing this many exams takes some serious effort :P
Ryu

Re:PIT fast?

Post by Ryu »

Bob the Avenger wrote: 100ms every 6hours is very accurate for the PIT, what rate have you set the timer for?
I use the internal frequency of the PIT, I believe this is precisely 1,193,180Hz on each counter. So how many the PIT ever counts (decremented from counter register) is added to SystemCounter, then basically I divide the 64bit SystemCounter with 1,193,180 to get my seconds.

IRQ-0 (PIT counter-0) is running at 2kHz output just for testing though, as this would be around 60-200Hz when I finalize this. But this counter is just to read counter-2 nothing more ( or resolution frequency ).

edit: Infact It resulted 100ms every 8hrs but I have applied a give or take accuracy on differnt systems.
blip

Re:PIT fast?

Post by blip »

I've read that the PIT's frequency should be about 1,193,181.667 Hz and that early BIOS programmers for whatever reason used 1,193,180 Hz instead.

The source clock for everything I suppose was 14,318,180 Hz and you divide that by 4 to get 3,579,545 Hz and divide that by 3 to get the PIT frequency. You can use this last step to be more accurate by using A = 3579545 / ( 3 * B ). But 1,193,182 Hz should be accurate enough for most purposes.

If you divide 14,318,180 Hz by 3 you get 4,772,726.67 Hz which just happens to be the input clock for an 8088/8086.
Ryu

Re:PIT fast?

Post by Ryu »

Nice, thanks blip for the more precise input frequency. After my post I realised I did a boo boo. My code to get my seconds was based on milliseconds -> SystemCounter/1,193 which should be SystemCounter/1,193.180 but now will be divided by 1,193.181667

Woo I really think this would be pretty darn precise. I was trying to achieve about 100ms off each day but I think they will be even more precise now.. Welp I will do the modifications this weekend and do a full 8hr test on real hardware.
blip

Re:PIT fast?

Post by blip »

I checked the OSFAQ and it talks about all the frequency divisions in hardware: http://www.osdev.org/osfaq2/index.php/PIT and it has some cool (though untested) example code for further accuracy on frequencies the hardware doesn't directly support but the code approximately emulates.

HelpPC has an interesting tidbit "the value of 1.19318MHz is derived from (4.77/4 MHz) and has it's roots based on NTSC frequencies". It and the OSFAQ conflict a bit though since the OSFAQ says the division by 12 is performed by ANDing two signals that are 14,318,180 Hz divided by 3 and 4.
Kemp

Re:PIT fast?

Post by Kemp »

Or you can just sync continuously, like you are supposed to do, so that you can estimate and average latency to server and such.
Well I didn't mean just do a single "what's the time now?" and then stop :P But doing it constantly all day is just pointless network congestion, and even more interrupts to deal with ;) Especially when you only lose less than half a second a day, which no-one is going to notice.
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:PIT fast?

Post by Pype.Clicker »

blip wrote: HelpPC has an interesting tidbit "the value of 1.19318MHz is derived from (4.77/4 MHz) and has it's roots based on NTSC frequencies". It and the OSFAQ conflict a bit though since the OSFAQ says the division by 12 is performed by ANDing two signals that are 14,318,180 Hz divided by 3 and 4.
I don't see a conflict here: i see complementary information... One (the HelpPc) says why you got that value and the other says how you can get it (out of a single quartz oscillator at 14.3... MHz) Frequency division is a simple thing to do with electronics: you feed a counter and extract the bits you're interested in, optionnally resetting the counter on certain conditions (e.g. for divide-by-three).
blip

Re:PIT fast?

Post by blip »

I know in the end the result is the same but specifically I was focusing on the original IBM PC without actually saying so. Everything is based off of that, not exactly of course, but I guess it doesn't really matter how it's done since PCs these days have blackbox-like chipsets that perform the function of all these legacy devices. The difference of hows isn't so important when you're OSdeving. *shrug*
Either way I'm still awaiting Ryu's results. :)
Bob the Avenger

Re:PIT fast?

Post by Bob the Avenger »

Ryu's results should be interresting, i should also get round to testing the drift i get too, but all good things come to those who procrastonate
srg_13

Re:PIT fast?

Post by srg_13 »

I find that in bochs, when I run my OS, the PIT is 2 or three times faster than usual. It works fine in a normal PC. Why is this happening? It doesn't matter yet, as at the moment it just makes the splash screen pop up for about half a second, but later when I do a floppy driver, the delays will be important, as I use a real floppy when testing in bochs.

-Stephen
Post Reply