RTC
-- Sebastian Pawlak, 2005.
Ustawianie czasu zegara czasu rzeczywistego (RTC - Real Time Clock).
Kod źródłowy pliku "rtc.c":
/* rtc: test wpisywania czasu systemowego do RTC
* Sebastian Pawlak, 2005.
*/
#include <stdio.h>
#include <sys/io.h> /* dla inb(), outb(), ioperm(); */
#include <stdlib.h> /* dla exit(); */
#include <time.h>
enum {
FALSE = 0,
TRUE = 1
};
#define ATOMIC_TOP \
{ \
const int interrupts_were_enabled = interrupts_enabled; \
__asm__ volatile ("cli"); \
interrupts_enabled = FALSE;
#define ATOMIC_BOTTOM \
if (interrupts_were_enabled) { \
__asm__ volatile ("sti"); \
interrupts_enabled = TRUE; \
} \
}
#define BIN2BCD(val) ((((val) / 10) << 4) + (val) % 10)
static int interrupts_enabled;
void setRTC(const struct tm itm_time);
int main(void)
{
struct tm itm_time;
itm_time.tm_hour =15;
itm_time.tm_min=30;
itm_time.tm_sec = 44;
if (iopl(3) != 0) {
fprintf(stderr, "Problem z iopl()!\n");
return -1;
}
setRTC(itm_time);
if (iopl(0) != 0) {
fprintf(stderr, "Problem z iopl()!\n");
return -1;
}
return 0;
}
/* rtcRead: odczytuje dane z portu rtc
*/
static inline unsigned char rtcRead(const unsigned char reg)
{
unsigned char ret;
ATOMIC_TOP
outb(reg & 0x7F, 0x70);
ret = inb(0x71);
ATOMIC_BOTTOM
return ret;
}
/* rtcWrite: zapisuje dane do portu rtc
*/
static inline void rtcWrite(unsigned char reg, unsigned char val)
{
outb(reg & 0x7F, 0x70);
outb(val, 0x71);
}
/* setRTC: zapisuje czas do zegara sprzetowego
*/
void setRTC(const struct tm itm_time)
{
int i = 9;
unsigned char saveControl, saveFreqSelect;
fprintf(stdout, "h: %d, m: %d, s: %d\n",
itm_time.tm_hour, itm_time.tm_min, itm_time.tm_sec);
ATOMIC_TOP
saveControl = rtcRead(11);
rtcWrite(11, (saveControl | 0x80));
saveFreqSelect = rtcRead(10);
rtcWrite(10, (saveFreqSelect | 0x70));
rtcWrite(0, BIN2BCD(itm_time.tm_sec));
rtcWrite(2, BIN2BCD(itm_time.tm_min));
rtcWrite(4, BIN2BCD(itm_time.tm_hour));
rtcWrite(11, saveControl);
rtcWrite(10, saveFreqSelect);
ATOMIC_BOTTOM
}





