1
1
#include <stdint.h>
2
+ #include <time.h>
2
3
3
4
#include "../bus/i2c/i2c.h"
4
5
#include "../bus/uart/uart.h"
8
9
#include "light.h"
9
10
#include "rtc.h"
10
11
11
- response_t RTC_SetTime (void ) {
12
-
12
+ // This bit is used to enable the oscillator. When negated, the oscillator is disabled.
13
+ static uint8_t const oscillator_enable = 0x7F ;
14
+
15
+ static uint8_t data_to_bcd (uint8_t data ){
16
+ uint8_t bcd = data ;
17
+
18
+ if (data >= 10 ){
19
+ uint8_t left = data / 10 ;
20
+ uint8_t right = data % 10 ;
21
+ bcd = (left << 4 ) | right ;
22
+ }
23
+ return bcd ;
24
+ }
25
+
26
+ static uint8_t bcd_to_data (uint8_t bcd ){
27
+ uint8_t right = (0xF & bcd );
28
+ uint8_t left = (bcd >> 4 ) & 0xF ;
29
+
30
+ left *= 10 ;
31
+ return left + right ;
32
+ }
33
+
34
+ response_t RTC_SetTime (uint32_t const * const unix_timestamp ) {
35
+
36
+ time_t timestamp = (time_t ) * unix_timestamp ;
37
+ struct tm * tm_info ;
38
+
39
+ tm_info = gmtime (& timestamp );
40
+ uint8_t sec = tm_info -> tm_sec ;
41
+ uint8_t min = tm_info -> tm_min ;
42
+ uint8_t hours = tm_info -> tm_hour ;
43
+ uint8_t day = tm_info -> tm_wday + 1 ;
44
+ uint8_t date = tm_info -> tm_mday ;
45
+ uint8_t month = tm_info -> tm_mon + 1 ;
46
+ uint8_t year = tm_info -> tm_year % 100 ; // Tm_year starts from 00 which means(1900).
47
+ // ds1307 only stores the last 2 digits.
48
+ if (sec == 60 )
49
+ sec = 0 ;
50
+
51
+ // Default 24 hrs format.
13
52
uint8_t buffer [9 ];
14
53
buffer [0 ] = DS1307_DATA_REG_SECONDS ;
15
- buffer [1 ] = UART1_Read ( ) & 0x7F ; // seconds
16
- buffer [2 ] = UART1_Read (); // minutes
17
- buffer [3 ] = UART1_Read ( ); // hours
18
- buffer [4 ] = UART1_Read (); // day
19
- buffer [5 ] = UART1_Read (); // date
20
- buffer [6 ] = UART1_Read (); // month
21
- buffer [7 ] = UART1_Read (); // year
22
- buffer [8 ] = UART1_Read (); // control
54
+ buffer [1 ] = data_to_bcd ( sec ) & oscillator_enable ; // seconds
55
+ buffer [2 ] = data_to_bcd ( min ); // minutes
56
+ buffer [3 ] = data_to_bcd ( hours ); // hours (hrs format)
57
+ buffer [4 ] = data_to_bcd ( day ); // day
58
+ buffer [5 ] = data_to_bcd ( date ); // date
59
+ buffer [6 ] = data_to_bcd ( month ); // month
60
+ buffer [7 ] = data_to_bcd ( year ); // year
61
+ buffer [8 ] = 0 ; // control
23
62
24
63
I2C_InitializeIfNot (I2C_BAUD_RATE_100KHZ , I2C_ENABLE_INTERRUPTS );
25
64
26
65
return I2C_BulkWrite (buffer , 9 , DS1307_I2C_DEVICE_ADDRESS );
27
66
}
28
67
68
+ response_t RTC_CmdSetTime (void ) {
69
+ uint32_t unix_timestamp = UART1_read_u32 ();
70
+
71
+ response_t res = RTC_SetTime (& unix_timestamp );
72
+ return res ;
73
+ }
74
+
29
75
response_t RTC_SetDigit (void ) {
30
76
31
77
uint8_t buffer [2 ];
@@ -37,20 +83,42 @@ response_t RTC_SetDigit(void) {
37
83
return I2C_BulkWrite (buffer , 2 , DS1307_I2C_DEVICE_ADDRESS );
38
84
}
39
85
40
- response_t RTC_GetTime (void ) {
86
+ response_t RTC_GetTime (uint32_t * unix_timestamp ) {
41
87
42
88
uint8_t buffer [7 ];
89
+ struct tm tm_info ;
43
90
44
91
I2C_InitializeIfNot (I2C_BAUD_RATE_100KHZ , I2C_ENABLE_INTERRUPTS );
45
92
46
93
if (I2C_BulkRead (DS1307_DATA_REG_SECONDS , DS1307_I2C_DEVICE_ADDRESS , buffer , 7 ) == SUCCESS ) {
47
- uint8_t i ;
48
- for (i = 0 ; i < sizeof (buffer ); i ++ ) UART1_Write (buffer [i ]);
94
+
95
+ // Need to convert from bcd to int.
96
+ tm_info .tm_sec = bcd_to_data (buffer [0 ]);
97
+ tm_info .tm_min = bcd_to_data (buffer [1 ]);
98
+ tm_info .tm_hour = bcd_to_data (buffer [2 ]);
99
+ tm_info .tm_wday = bcd_to_data (buffer [3 ]) - 1 ;
100
+ tm_info .tm_mday = bcd_to_data (buffer [4 ]);
101
+ tm_info .tm_mon = bcd_to_data (buffer [5 ]) - 1 ;
102
+ tm_info .tm_year = 100 + bcd_to_data (buffer [6 ]); // 100 means for year 2000 (2000 - 1900)
103
+
104
+ tm_info .tm_sec = tm_info .tm_sec & oscillator_enable ;
105
+
106
+ uint32_t timestamp = (uint32_t ) mktime (& tm_info );
107
+ * unix_timestamp = timestamp ;
49
108
} else return FAILED ;
50
109
51
110
return SUCCESS ;
52
111
}
53
112
113
+ response_t RTC_CmdGetTime (void ){
114
+ uint32_t unix_timestamp ;
115
+ response_t res = RTC_GetTime (& unix_timestamp );
116
+
117
+ // What if error occurs here, Returns fail.
118
+ UART1_write_u32 (unix_timestamp );
119
+ return res ;
120
+ }
121
+
54
122
response_t RTC_GetDigit (void ) {
55
123
56
124
uint8_t buffer [1 ];
0 commit comments