Subversion Repositories Code-Repo

Rev

Rev 281 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
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
}