| 281 |
Kevin |
1 |
#include "defines.h"
|
|
|
2 |
#include "DS3231.h"
|
|
|
3 |
#include "I2C1.h"
|
|
|
4 |
|
|
|
5 |
void DS3231_Init() {
|
|
|
6 |
uint8_t 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 |
I2C1_Master_Send(DS3231_ADDRESS, 3, reg);
|
|
|
28 |
while (!I2C1_Get_Status());
|
|
|
29 |
}
|
|
|
30 |
|
|
|
31 |
uint8_t DS3231_Get_Status(void) {
|
|
|
32 |
/* Status Register (0x0F)
|
|
|
33 |
* Bit 7 - OSF
|
|
|
34 |
* Bit 3 - EN32kHz
|
|
|
35 |
* Bit 2 - BSY
|
|
|
36 |
* Bit 1 - A2F
|
|
|
37 |
* Bit 0 - A1F
|
|
|
38 |
*/
|
|
|
39 |
uint8_t value;
|
|
|
40 |
I2C1_Master_Restart(DS3231_ADDRESS, 0x0F, 1);
|
|
|
41 |
while (!I2C1_Get_Status());
|
|
|
42 |
I2C1_Read_Buffer(&value);
|
|
|
43 |
return value;
|
|
|
44 |
}
|
|
|
45 |
|
|
|
46 |
void DS3231_Set_Time(DS3231_TIME *time) {
|
|
|
47 |
|
|
|
48 |
// Format the data in a way that the chip expects
|
|
|
49 |
#ifndef DS3231_TIME_ONLY
|
|
|
50 |
uint8_t output[8];
|
|
|
51 |
#else
|
|
|
52 |
uint8_t output[4];
|
|
|
53 |
#endif
|
|
|
54 |
output[0] = DS3231_SECONDS;
|
|
|
55 |
output[1] = ((time->sec / 10) << 4) | (time->sec % 10);
|
|
|
56 |
output[2] = ((time->min / 10) << 4) | (time->min % 10);
|
|
|
57 |
output[3] = ((time->hour / 10) << 4) | (time->hour % 10);
|
|
|
58 |
#ifndef DS3231_TIME_ONLY
|
|
|
59 |
if (!time->h_mil) {
|
|
|
60 |
output[3] |= (time->h_am_pm) ? 0x60 : 0x40;
|
|
|
61 |
}
|
|
|
62 |
output[4] = time->day;
|
|
|
63 |
output[5] = ((time->date / 10) << 4) | (time->date % 10);
|
|
|
64 |
output[6] = ((time->month / 10) << 4) | (time->month % 10);
|
|
|
65 |
output[7] = ((time->year / 10) << 4) | (time->year % 10);
|
|
|
66 |
#endif
|
|
|
67 |
|
|
|
68 |
// Check the status to make sure that it isnt currently busy
|
|
|
69 |
while (DS3231_Get_Status() & 0x04);
|
|
|
70 |
|
|
|
71 |
// Write the data to the chip
|
|
|
72 |
#ifndef DS3231_TIME_ONLY
|
|
|
73 |
I2C1_Master_Send(DS3231_ADDRESS, 8, output);
|
|
|
74 |
#else
|
|
|
75 |
I2C1_Master_Send(DS3231_ADDRESS, 4, output);
|
|
|
76 |
#endif
|
|
|
77 |
while (!I2C1_Get_Status());
|
|
|
78 |
}
|
|
|
79 |
|
|
|
80 |
void DS3231_Get_Time(DS3231_TIME *time) {
|
|
|
81 |
|
|
|
82 |
// Check the status to make sure that it isnt currently busy
|
|
|
83 |
while (DS3231_Get_Status() & 0x04);
|
|
|
84 |
|
|
|
85 |
// Request time data from the chip
|
|
|
86 |
#ifndef DS3231_TIME_ONLY
|
|
|
87 |
uint8_t input[7];
|
|
|
88 |
I2C1_Master_Restart(DS3231_ADDRESS, 0x00, 7);
|
|
|
89 |
#else
|
|
|
90 |
uint8_t input[3];
|
|
|
91 |
I2C1_Master_Restart(DS3231_ADDRESS, 0x00, 3);
|
|
|
92 |
#endif
|
|
|
93 |
while (!I2C1_Get_Status());
|
|
|
94 |
I2C1_Read_Buffer(input);
|
|
|
95 |
|
|
|
96 |
// Parse BCD format into decimal and return
|
|
|
97 |
time->sec = ((input[0] >> 4) * 10) + (input[0] & 0x0F);
|
|
|
98 |
time->min = ((input[1] >> 4) * 10) + (input[1] & 0x0F);
|
|
|
99 |
if (input[2] & 0x40) {
|
|
|
100 |
time->h_mil = 0;
|
|
|
101 |
time->h_am_pm = (input[2] & 0x20) ? 1 : 0;
|
|
|
102 |
time->hour = (((input[2] >> 4) & 0x01) * 10) + (input[2] & 0x0F);
|
|
|
103 |
} else {
|
|
|
104 |
time->h_mil = 1;
|
|
|
105 |
time->hour = ((input[2] >> 4) * 10) + (input[2] & 0x0F);
|
|
|
106 |
}
|
|
|
107 |
#ifndef DS3231_TIME_ONLY
|
|
|
108 |
time->day = input[3];
|
|
|
109 |
time->date = ((input[4] >> 4) * 10) + (input[4] & 0x0F);
|
|
|
110 |
time->month = ((input[5] >> 4) * 10) + (input[5] & 0x0F);
|
|
|
111 |
time->year = ((input[6] >> 4) * 10) + (input[6] & 0x0F);
|
|
|
112 |
#endif
|
|
|
113 |
}
|