Programmable Interval Timer: Difference between revisions

m
Change mS to ms (SI unit for second is lower case 's' while upper case 'S' is Siemens)
[unchecked revision][unchecked revision]
(Later is meant instead of latter)
m (Change mS to ms (SI unit for second is lower case 's' while upper case 'S' is Siemens))
Line 22:
 
=== Channel 0 ===
The output from PIT channel 0 is connected to the PIC chip, so that it generates an "IRQ 0". Typically during boot the BIOS sets channel 0 with a count of 65535 or 0 (which translates to 65536), which gives an output frequency of 18.2065 Hz (or an IRQ every 54.9254 mSms). Channel 0 is probably the most useful PIT channel, as it is the only channel that is connected to an IRQ. It can be used to generate an infinte series of "timer ticks" at a frequency of your choice (as long as it is higher than 18 Hz), or to generate single CPU interrupts (in "one shot" mode) after programmable short delays (less than an 18th of a second).
 
When choosing an operating mode, below, it is useful to remember that the IRQ0 is generated by the ''rising edge'' of the Channel 0 output voltage (ie. the transition from "low" to "high", only).
Line 270:
The idea is to provide a single routine to initialize PIT channel 0 for any (possible) frequency and use IRQ 0 to accurately keep track of real time in milliseconds since the PIT was configured.
 
For the sake of accuracy, the initialization code will calculate the number of whole milliseconds to add to the "system timer tick" each IRQ, and the number of "fractions of a millisecond" to avoid drift. This may be important, for example if the PIT is set for 700 Hz it'd work out to (roughly) 1.42857 mSms between IRQs, so keeping track of whole milliseconds only would lead to huge inaccuracies.
 
Hopefully, everyone is familiar with fixed point mathematics. For example, with the "32.32" notation I'll be using, if the high 32-bit value is equal to 0x00000001 and the low 32-bit value is equal to 0x80000000 then the combined value would be 1.5. In a similar way, the fraction 0.75 is represented with 0xC000000, 0.125 is represented with 0x20000000 and 0.12345 would be represented with 0x1F9A6B50.
Line 278:
<source lang="asm">
section .bss
system_timer_fractions: resd 1 ; Fractions of 1 mSms since timer initialized
system_timer_mSsystem_timer_ms: resd 1 ; Number of whole mSms since timer initialized
IRQ0_fractions: resd 1 ; Fractions of 1 mSms between IRQs
IRQ0_mSIRQ0_ms: resd 1 ; Number of whole mSms between IRQs
IRQ0_frequency: resd 1 ; Actual frequency of PIT
PIT_reload_value: resw 1 ; Current PIT reload value
Line 295:
mov eax, [IRQ0_fractions]
mov ebx, [IRQ0_mSIRQ0_ms] ; eax.ebx = amount of time between IRQs
add [system_timer_fractions], eax ; Update system timer tick fractions
adc [system_timer_mSsystem_timer_ms], ebx ; Update system timer tick milli-seconds
mov al, 0x20
Line 387:
shr edx,10 ;edx:eax = reload_value * 3000 * (2^42) / 3579545 / (2^10)
mov [IRQ0_mSIRQ0_ms],edx ;Set whole mSms between IRQs
mov [IRQ0_fractions],eax ;Set fractions of 1 mSms between IRQs
Anonymous user