Programmable Interval Timer: Difference between revisions

[unchecked revision][unchecked revision]
Content deleted Content added
m Spelling, (retriggerable and prescaler are not words... should it be fixed?)
layout
Line 2:
 
 
=== The Oscillator ===
 
The oscillator used by the PIT chip runs at (roughly) 1.193182 MHz. The reason for this requires a trip back into history (to the latter half of the 1970's)...
Line 8:
The original PC used a single "base oscillator" to generate a frequency of 14.31818 MHz because this frequency was commonly used in television circuitry at the time. This base frequency was divided by 3 to give a frequency of 4.77272666 MHz that was used by the CPU, and divided by 4 to give a frequency of 3.579545 MHz that was used by the CGA video controller. By logically ANDing these signals together a frequency equivalent to the base frequency divided by 12 was created. This frequency is 1.1931816666 MHz (where the 6666 part is recurring). At the time it was a brilliant method of reducing costs, as the 14.31818 MHz oscillator was cheap due to mass production and it was cheaper to derive the other frequencies from this than to have several oscillators. In modern computers, where the cost of electronics is much less, and the CPU and video run at much higher frequencies the PIT lives on as a reminder of "the good ole' days".
 
=== Frequency Dividers ===
 
The basic principle of a frequency divider is to divide one frequency to obtain a slower frequency. This is typically done by using a counter. Each "pulse" from the input frequency causes the counter to be decreased, and when that counter has reached zero a pulse is generated on the output and the counter is reset. For example, if the input signal is 200 Hz and the counter is reset to a value of ten each time, then the output frequency would be 200/10, or 20 Hz.
Line 16:
Each PIT channel also has a "gate input" pin which can be used to control whether the input signal gets to the channel or not. For most of the PIT channels the associated gate input pin is not connected to anything (except for PIT channel 2).
 
=== PIT Timer Accuracy ===
 
The accuracy of the PIT timer depends on the quality of the oscillator used, and is typically accurate to within +/- 1.73 seconds per day. There are many causes for this inaccuracy, however because of this there isn't much point in specifying times or frequencies to more than five or six digits. Despite this, I like to be as accurate as possible!
 
=== Outputs ===
 
Each channel (or frequency divider) has an output signal that is used for a different purpose.
 
==== Channel 0 ====
 
The output for 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 65536, which gives an output frequency of 18.2065 Hz (or an IRQ every 54.9254 mS). Channel 0 is probably the most useful PIT channel, as it is the only channel that is connected to an IRQ.
 
==== Channel 1 ====
 
The output for PIT channel 1 was once used (in conjunction with the DMA controller's channel 0) for refreshing the DRAM (Dynamic Random Access Memory) or RAM. Typically, each bit in RAM consists of a capacitor which holds a tiny charge representing the state of that bit, however (due to leakage) these capacitors need to be "refreshed" periodically so that they don't forget their state.
Line 34:
On the AT and later machines, the DRAM refresh is done with dedicated hardware and the PIT (and DMA controller) is no longer used. On modern computers where the functionality of the PIT is implemented in a large scale integrated circuit, PIT channel 1 is no longer usable and may not be implemented at all.
 
==== Channel 2 ====
 
The output of PIT channel 2 is connected to the PC speaker, so that frequency of the output determines the frequency of the sound produced by the speaker. This is the only channel where the gate input can be controlled by software (via. bit 0 of I/O port 0x61), and the only channel where it's output can be read by software (via. bit 5 of I/O port 0x61). Details of how to program the PC speaker is outside the scope of this page.
 
=== I/O Ports ===
 
The PIT chip uses the following I/O ports:
Line 82:
The "BCD/Binary" bit determines if the PIT channel will operate in binary mode or BCD mode (where each 4 bits of the counter represent a decimal digit, and the counter holds values from '0000' to '9999'). 80x86 PCs don't use binary mode (BCD mode is ugly and limits the range of counts/frequencies possible). Although it should still be possible to use BCD mode, it may not work properly on some "compatible" chips. For the "read back" command and the "counter latch" command, this bit has different meanings (see the information corresponding to these commands below).
 
=== Operating Modes ===
 
While each operating mode behaves differently, some things are common to all operating modes. This includes:
Line 172:
The reload value can be changed at any time, however the new value will not effect the current count until the current count is reloaded (on the next rising edge of the gate input). When this occurs counting will continue using the new reload value.
 
=== Counter Latch Command ===
 
To prevent the current count from being updated, it is possible to "latch" a PIT channel using the latch command. To do this, send the value CC000000 (in binary) to the mode/command register (I/O port 0x43), where 'CC' corresponds to the channel number. When the latch command has been sent, the current count is copied into an internal "latch register" which can then be read via. the data port corresponding to the selected channel (I/O ports 0x40 to 0x42). The value kept in the latch register remains the same until it has been fully read, or until a new mode/command register is written.
Line 180:
While the latch command should not effect the current count, on some (old/dodgy) motherboards sending the latch command can cause a cycle of the input signal to be occasionally missed, which would cause the current count to be decremented 0.8381 uS later than it should be. If you're sending the latch command often this could cause accuracy problems (but IMHO if you need to send the latch command often you may wish to consider redesigning your code anyway).
 
=== Read Back Command ===
 
The read back command is a special command sent to the mode/command register (I/O port 0x43). The "read back" is not supported on the old 8253 chips but should be supported on all AT and later computers except for PS/2 (i.e. anything that isn't obsolete will support it).
Line 203:
If bit 4 is clear, then for any/all PIT channels selected with bits 1 to 3, the next read of the corresponding data port will return a status byte (discussed below).
 
==== Read Back Status Byte ====
 
After sending a read back command with bit 4 clear, reading the data port for each selected channel will return a status value with the following format:
Line 232:
Bit 6 indicates whether a newly-programmed divisor value has been loaded into the current count yet (if clear) or the channel is still waiting for a trigger signal or for the current count to count down to zero before a newly programmed reload value is loaded into the current count (if set). This bit is set when the mode/command register is initialized or when a new reload value is written, and cleared when the reload value is copied into the current count.
 
=== Reading The Current Count ===
 
To read the current count using the "lobyte only" or "hibyte only" access modes, you can just do an "in al,0x40" (for PIT channel 0) without problems. For frequencies higher than 4.7 KHz it can be easiest to set the high byte of the reload value to zero, and then use the "lobyte only" access mode to minimize hassles.
Line 251:
ret
 
=== Setting The Reload Value ===
 
To set the reload value, just sent the value/s to the corresponding data port. For the "lobyte only" or "hibyte only" access modes this only takes a single "out 0x40,al" (for PIT channel 0).
Line 269:
It should be notes that a reload value of zero can be used to specify a divisor of 65536. This is how the BIOS gets an IRQ 0 frequency as low as 18.2065 Hz.
 
=== PIT Channel 0 Example Code ===
 
To complete this page I've to included the following example code. This code was written for NASM, but hasn't been tested.