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
}
w3cw3c
automatyka przemysłowa