aboutsummaryrefslogtreecommitdiffstats
path: root/ds3231.c
blob: b70a09bdef8592be7ddd7176adc3e53e91772dcc (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
/*
 * File: Header file to use DS3231 RTC module with PIC16F877A
 * Author: B.Aswinth Raj
 * Created on 5 May, 2018, 10:06 PM
 * Connect the RTC module to SDA and SCK pins of the PIC.
 * This header needs the PIC16f877a_I2C.h header to compile
 */


//PIN 18 -> RC3 -> SCL
//PIN 23 -> RC4 ->SDA

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

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

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
}

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_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_Repeated_Start(); // Restart I2C

    //READ
    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
}