| 160 |
Kevin |
1 |
#include "defines.h"
|
|
|
2 |
#include "sensor_rtc_DS3231.h"
|
|
|
3 |
#include "base_I2C.h"
|
|
|
4 |
|
|
|
5 |
void DS3231_Begin() {
|
|
|
6 |
char reg[3];
|
|
|
7 |
reg[0] = DS3231_CONTROL;
|
|
|
8 |
|
|
|
9 |
/* Control Register (0x0E)
|
|
|
10 |
* Bit 7 - !EOSC
|
|
|
11 |
* Bit 6 - BBSQW
|
|
|
12 |
* Bit 5 - CONV
|
|
|
13 |
* Bit 4 - RS2
|
|
|
14 |
* Bit 3 - RS1
|
|
|
15 |
* Bit 2 - INTCN
|
|
|
16 |
* Bit 1 - A2IE
|
|
|
17 |
* Bit 0 - A1IE
|
|
|
18 |
*/
|
|
|
19 |
reg[1] = 0x04;
|
|
|
20 |
|
|
|
21 |
/* Control Register 2 (0x0F)
|
|
|
22 |
* Bit 3 = EN32kHZ
|
|
|
23 |
*/
|
|
|
24 |
reg[2] = 0x00;
|
|
|
25 |
|
|
|
26 |
// Set the configuration registers
|
|
|
27 |
I2C_Master_Send(DS3231_ADDRESS, 3, reg);
|
|
|
28 |
char result;
|
|
|
29 |
do {
|
|
|
30 |
result = I2C_Get_Status();
|
|
|
31 |
} while (!result);
|
|
|
32 |
}
|
|
|
33 |
|
|
|
34 |
char DS3231_Get_Status(void) {
|
|
|
35 |
/* Status Register (0x0F)
|
|
|
36 |
* Bit 7 - OSF
|
|
|
37 |
* Bit 3 - EN32kHz
|
|
|
38 |
* Bit 2 - BSY
|
|
|
39 |
* Bit 1 - A2F
|
|
|
40 |
* Bit 0 - A1F
|
|
|
41 |
*/
|
|
|
42 |
char value;
|
|
|
43 |
I2C_Master_Restart(DS3231_ADDRESS, 0x0F, 1);
|
|
|
44 |
char result;
|
|
|
45 |
do {
|
|
|
46 |
result = I2C_Get_Status();
|
|
|
47 |
} while (!result);
|
|
|
48 |
I2C_Read_Buffer(&value);
|
|
|
49 |
return value;
|
|
|
50 |
}
|
|
|
51 |
|
|
|
52 |
void DS3231_Set_Time(char sec, char min, char hour, char day, char date,
|
|
|
53 |
char month, char year, char h_mil, char h_am_pm) {
|
|
|
54 |
|
|
|
55 |
// Format the data in a way that the chip expects
|
|
|
56 |
char output[8];
|
|
|
57 |
output[0] = DS3231_SECONDS;
|
|
|
58 |
output[1] = ((sec / 10) << 4) | (sec % 10);
|
|
|
59 |
output[2] = ((min / 10) << 4) | (min % 10);
|
|
|
60 |
output[3] = ((hour / 10) << 4) | (hour % 10);
|
|
|
61 |
if (!h_mil) {
|
|
|
62 |
output[3] |= (h_am_pm) ? 0x60 : 0x40;
|
|
|
63 |
}
|
|
|
64 |
output[4] = day;
|
|
|
65 |
output[5] = ((date / 10) << 4) | (date % 10);
|
|
|
66 |
output[6] = ((month / 10) << 4) | (month % 10);
|
|
|
67 |
output[7] = ((year / 10) << 4) | (year % 10);
|
|
|
68 |
|
|
|
69 |
// Check the status to make sure that it isnt currently busy
|
|
|
70 |
char status = DS3231_Get_Status();
|
|
|
71 |
while (status & 0x04)
|
|
|
72 |
status = DS3231_Get_Status();
|
|
|
73 |
|
|
|
74 |
// Write the data to the chip
|
|
|
75 |
I2C_Master_Send(DS3231_ADDRESS, 8, output);
|
|
|
76 |
char result;
|
|
|
77 |
do {
|
|
|
78 |
result = I2C_Get_Status();
|
|
|
79 |
} while (!result);
|
|
|
80 |
}
|
|
|
81 |
|
|
|
82 |
void DS3231_Get_Time(char *sec, char *min, char *hour, char *day, char *date,
|
|
|
83 |
char *month, char *year, char *h_mil, char *h_am_pm) {
|
|
|
84 |
|
|
|
85 |
// Check the status to make sure that it isnt currently busy
|
|
|
86 |
char status = DS3231_Get_Status();
|
|
|
87 |
while (status & 0x04)
|
|
|
88 |
status = DS3231_Get_Status();
|
|
|
89 |
|
|
|
90 |
// Request time data from the chip
|
|
|
91 |
char input[7];
|
|
|
92 |
I2C_Master_Restart(DS3231_ADDRESS, 0x00, 7);
|
|
|
93 |
char result;
|
|
|
94 |
do {
|
|
|
95 |
result = I2C_Get_Status();
|
|
|
96 |
} while (!result);
|
|
|
97 |
I2C_Read_Buffer(input);
|
|
|
98 |
|
|
|
99 |
// Parse BCD format into decimal and return
|
|
|
100 |
*sec = ((input[0] >> 4) * 10) + (input[0] & 0x0F);
|
|
|
101 |
*min = ((input[1] >> 4) * 10) + (input[1] & 0x0F);
|
|
|
102 |
if (input[2] & 0x40) {
|
|
|
103 |
*h_mil = 0;
|
|
|
104 |
*h_am_pm = (input[2] & 0x20) ? 1 : 0;
|
|
|
105 |
*hour = (((input[2] >> 4) & 0x01) * 10) + (input[2] & 0x0F);
|
|
|
106 |
} else {
|
|
|
107 |
*h_mil = 1;
|
|
|
108 |
*hour = ((input[2] >> 4) * 10) + (input[2] & 0x0F);
|
|
|
109 |
}
|
|
|
110 |
*day = input[3];
|
|
|
111 |
*date = ((input[4] >> 4) * 10) + (input[4] & 0x0F);
|
|
|
112 |
*month = ((input[5] >> 4) * 10) + (input[5] & 0x0F);
|
|
|
113 |
*year = ((input[6] >> 4) * 10) + (input[6] & 0x0F);
|
|
|
114 |
}
|