aboutsummaryrefslogtreecommitdiffstats
path: root/ds3231.c
blob: b4e7ff9d6684be18334de7cc9029eb7d0c4f2262 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
//PIN 18 -> RC3 -> SCL
//PIN 23 -> RC4 ->SDA

/****** Functions for RTC module *******/

#include "ds3231.h"
#include "i2c.h"
#include "main.h"

// Initialize character array for days of the week
char dayOfWeek[7][4] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};

// Initialize character array for months of the year
char monthOfYear[12][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
    "Aug", "Sep", "Oct", "Nov", "Dec"};

int BCD_2_DEC(int to_convert) {
    return (to_convert >> 4) * 10 + (to_convert & 0x0F);
}

int DEC_2_BCD(int to_convert) {
    return ((to_convert / 10) << 4) + (to_convert % 10);
}

unsigned int Get_DayOfWeek(unsigned int y, unsigned int m, unsigned int d) {
    return (d += m < 3 ? y-- : y - 2, 23 * m / 9 + d + 4 + y / 4 - y / 100 + y / 400) % 7 + 1; // 01 - 07, 01 = Sunday
}

unsigned int Get_Days_In_Month(unsigned int y, unsigned int m) {
    return (m == 2) ?
            (28 + Get_Is_Leap_Year(y)) : 31 - (m - 1) % 7 % 2;
}

unsigned int Get_Is_Leap_Year(unsigned int y) {
    return (year % 4) || ((year % 100 == 0) && (year % 400)) ? 0 : 1;
}

char* Get_WeekDay(unsigned int d){
    return dayOfWeek[d - 1];
}

void Read_Alarms_Temp() {
    I2C_Master_Start(); // Start I2C
    I2C_Master_Write(0xD0); // RTC chip address
    I2C_Master_Write(0x07); // (alarm1 seconds register)
    I2C_Master_Repeated_Start(); // Restart I2C

    //READ
    I2C_Master_Write(0xD1); // Initialize data read
    alarm1_sec = BCD_2_DEC(I2C_Master_Read(1)); // Read alarm1 seconds 07h
    alarm1_min = BCD_2_DEC(I2C_Master_Read(1)); // Read alarm1 minutes 08h
    alarm1_hour = BCD_2_DEC(I2C_Master_Read(1)); // Read alarm1 hours 09h
    I2C_Master_Read(1); // skip alarm1 day/date 0Ah
    alarm2_min = BCD_2_DEC(I2C_Master_Read(1)); // Read alarm2 minutes 0Bh
    alarm2_hour = BCD_2_DEC(I2C_Master_Read(1)); // Read alarm2 hours 0Ch
    I2C_Master_Read(1); // Skip alarm2 day/date 0Dh
    control_reg = I2C_Master_Read(1); // Read control register 0Eh
    status_reg = I2C_Master_Read(1); // Read status register 0Fh
    I2C_Master_Read(1); // Skip aging offset register

    temperature_msb = I2C_Master_Read(1); // Read temperature MSB 011h

    temperature_lsb = I2C_Master_Read(0); // Read temperature LSB 012h
    I2C_Master_Stop();
}

void Set_Date() {
    I2C_Master_Start(); // Start I2C
    I2C_Master_Write(0xD0); // RTC Chip address
    I2C_Master_Write(4); // send register address
    I2C_Master_Write(DEC_2_BCD(date)); //update date
    I2C_Master_Write(DEC_2_BCD(month)); //update month
    I2C_Master_Write(DEC_2_BCD(year)); //update year
    I2C_Master_Stop();
}

void Set_DayOfWeek(int dow) {
    I2C_Master_Start(); // Start I2C
    I2C_Master_Write(0xD0); // RTC Chip address
    I2C_Master_Write(3); // send register address
    I2C_Master_Write(dow); //update day of week
    I2C_Master_Stop();
}

void Set_Sqwe(int contvalue) {
    I2C_Master_Start(); // Start I2C
    I2C_Master_Write(0xD0); // RTC Chip address
    I2C_Master_Write(0x0E); // Control register address
    I2C_Master_Write(contvalue); // Data to control register
    I2C_Master_Stop();
}

void Set_Time() {
    I2C_Master_Start(); // Start I2C
    I2C_Master_Write(0xD0); // RTC Chip address
    I2C_Master_Write(0); // send register address
    I2C_Master_Write(DEC_2_BCD(sec)); //update sec
    I2C_Master_Write(DEC_2_BCD(min)); //update min
    I2C_Master_Write(DEC_2_BCD(hour)); //update hour
    I2C_Master_Stop();
}

void Update_Current_Date_Time() {
    //START to Read
    I2C_Master_Start();
    I2C_Master_Write(0xD0); // RTC Chip address
    I2C_Master_Write(0);
    I2C_Master_Stop(); // Restart I2C

    //READ
    I2C_Master_Start();
    I2C_Master_Write(0xD1); // Initialize data read
    sec = BCD_2_DEC(I2C_Master_Read(1)); // Read sec from register 00h
    min = BCD_2_DEC(I2C_Master_Read(1)); // Read min from register 01h
    hour = BCD_2_DEC(I2C_Master_Read(1)); // Read hour from register 02h
    day = I2C_Master_Read(1); // Read day from register 03h
    date = BCD_2_DEC(I2C_Master_Read(1)); // Read date from register 04h
    month = BCD_2_DEC(I2C_Master_Read(1)); // Read month from register 05h
    year = BCD_2_DEC(I2C_Master_Read(1)); // Read year from register 06h
    I2C_Master_Stop();

    //END Reading

    I2C_Master_Start();
    I2C_Master_Write(0xD1);
    I2C_Master_Read(1);
    I2C_Master_Stop();
}

void Write_Alarms() {
    I2C_Master_Start(); // Start I2C
    I2C_Master_Write(0xD0); // RTC Chip Address
    I2C_Master_Write(7); // Send Alarm1 register address
    I2C_Master_Write(0); // Write 0 to Alarm1 seconds
    I2C_Master_Write(DEC_2_BCD(alarm1_min)); // Write Alarm1 minutes
    I2C_Master_Write(DEC_2_BCD(alarm1_hour)); // Write Alarm1 hours
    I2C_Master_Write(0x80); // Alarm1 when H:M:S matches
    I2C_Master_Write(DEC_2_BCD(alarm2_min)); // Write Alarm2 minutes
    I2C_Master_Write(DEC_2_BCD(alarm2_hour)); // Write Alarm2 hours
    I2C_Master_Write(0x80); // Alarm2 when H:M:S matches

    //Write data to control register (enable interupt when alarm);
    I2C_Master_Write(4 | alarm1_status | (alarm2_status << 1));
    I2C_Master_Write(0); // Clear alarm flag bits
    I2C_Master_Stop(); // Stop I2C
    __delay_ms(200); // Wait 200ms
}