RTC: Difference between revisions

Jump to navigation Jump to search
90 bytes added ,  29 days ago
m
Bot: Replace deprecated source tag with syntaxhighlight
[unchecked revision][unchecked revision]
No edit summary
m (Bot: Replace deprecated source tag with syntaxhighlight)
 
Line 30:
at offset 0xA, 0xB, and 0xC in the CMOS RAM. To write 0x20 to Status Register A you would do this:
 
<sourcesyntaxhighlight lang="C">
disable_ints(); // important that no interrupts happen (perform a CLI)
outportb(0x70, 0x8A); // select Status Register A, and disable NMI (by setting the 0x80 bit)
outportb(0x71, 0x20); // write to CMOS/RTC RAM
enable_ints(); // (perform an STI) and reenable NMI if you wish
</syntaxhighlight>
</source>
 
Other bytes of the CMOS RAM are used by the RTC for other functions, or by the [[BIOS]] and other such services.
Line 47:
To turn on the periodic interrupt, all you have to do is:
 
<sourcesyntaxhighlight lang="C">
disable_ints(); // disable interrupts
outportb(0x70, 0x8B); // select register B, and disable NMI
Line 54:
outportb(0x71, prev | 0x40); // write the previous value ORed with 0x40. This turns on bit 6 of register B
enable_ints();
</syntaxhighlight>
</source>
 
This will turn on the IRQ with the default 1024 Hz rate. Be sure that you install the IRQ handler before you enable the RTC
Line 64:
A value of 0 disables the interrupt. To calculate a new frequency:
 
<sourcesyntaxhighlight lang="C">
frequency = 32768 >> (rate-1);
</syntaxhighlight>
</source>
 
"Rate" is the divider setting. If you select a rate of 1 or 2, the RTC will have problems and "roll over" so that it
Line 72:
rate you can select is 3. This will generate interrupts of 8 kHz or 122 uS. To change the rate:
 
<sourcesyntaxhighlight lang="C">
rate &= 0x0F; // rate must be above 2 and not over 15
disable_ints();
Line 80:
outportb(0x71, (prev & 0xF0) | rate); //write only our rate to A. Note, rate is the bottom 4 bits.
enable_ints();
</syntaxhighlight>
</source>
 
===Interrupts and Register C===
Line 88:
it is, just attach this code to the bottom of your IRQ handler to be sure you get another interrupt. If you're using Bochs, it is also recommended to read Status Register C after initialising the RTC, to make sure any RTC interrupts that were pending before/while the RTC was initialised are acknowledged (not doing this has lead to the RTC timer not sending any interrupts after rebooting in at least one case, observed on Bochs 2.6.6, [http://forum.osdev.org/viewtopic.php?f=1&t=30091 see this thread]).
 
<sourcesyntaxhighlight lang="C">
outportb(0x70, 0x0C); // select register C
inportb(0x71); // just throw away contents
</sourcesyntaxhighlight>
 
==Problems?==
Cookies help us deliver our services. By using our services, you agree to our use of cookies.

Navigation menu