Merge branch 'master' into prog-loader
[lunaix-os.git] / lunaix-os / hal / rtc.c
1 /**
2  * @file rtc.c
3  * @author Lunaixsky
4  * @brief RTC & CMOS abstraction. Reference: MC146818A & Intel Series 500 PCH datasheet
5  * @version 0.1
6  * @date 2022-03-07
7  * 
8  * @copyright Copyright (c) 2022
9  * 
10  */
11 #include <hal/rtc.h>
12 #include <klibc/string.h>
13
14 void
15 rtc_init() {
16     uint8_t regA = rtc_read_reg(RTC_REG_A | WITH_NMI_DISABLED);
17     regA = (regA & ~0x7f) | RTC_FREQUENCY_1024HZ | RTC_DIVIDER_33KHZ;
18     rtc_write_reg(RTC_REG_A | WITH_NMI_DISABLED, regA);
19
20     // Make sure the rtc timer is disabled by default
21     rtc_disable_timer();
22 }
23
24 uint8_t
25 rtc_read_reg(uint8_t reg_selector)
26 {
27     io_outb(RTC_INDEX_PORT, reg_selector);
28     return io_inb(RTC_TARGET_PORT);
29 }
30
31 void
32 rtc_write_reg(uint8_t reg_selector, uint8_t val)
33 {
34     io_outb(RTC_INDEX_PORT, reg_selector);
35     io_outb(RTC_TARGET_PORT, val);
36 }
37
38 uint8_t
39 bcd2dec(uint8_t bcd)
40 {
41     return ((bcd & 0xF0) >> 1) + ((bcd & 0xF0) >> 3) + (bcd & 0xf);
42 }
43
44
45 void
46 rtc_enable_timer() {
47     uint8_t regB = rtc_read_reg(RTC_REG_B | WITH_NMI_DISABLED);
48     rtc_write_reg(RTC_REG_B | WITH_NMI_DISABLED, regB | RTC_TIMER_ON);
49 }
50
51 void
52 rtc_disable_timer() {
53     uint8_t regB = rtc_read_reg(RTC_REG_B | WITH_NMI_DISABLED);
54     rtc_write_reg(RTC_REG_B | WITH_NMI_DISABLED, regB & ~RTC_TIMER_ON);
55 }