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 }