Skip to content

Commit 80f021d

Browse files
authored
Implement get_fattime (#160)
* rtc_settime, rtc_gettime functions added * wrapper funcs, bcd_to_data conversion * update example using rtc_gettime Signed-off-by: Hrushi20 <[email protected]>
1 parent d6f594a commit 80f021d

File tree

5 files changed

+132
-31
lines changed

5 files changed

+132
-31
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Makefile
88

99
*.dump
1010
.vscode/*
11+
.idea/*
1112

1213
*~*
1314
\#*\#

src/commands.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ command_func_t* const cmd_table[NUM_PRIMARY_CMDS + 1][NUM_SECONDARY_CMDS_MAX + 1
281281
},
282282
{ // 13 SENSORS
283283
// 0 1 RTC_SETTIME 2 RTC_SETDIGIT 3 RTC_GETTIME
284-
Undefined, RTC_SetTime, RTC_SetDigit, RTC_GetTime,
284+
Undefined, RTC_CmdSetTime, RTC_SetDigit, RTC_CmdGetTime,
285285
// 4 RTC_GETDIGIT 5 HCSR04 6 AM2302 7 BMP180
286286
RTC_GetDigit, Unimplemented, Unimplemented, Unimplemented,
287287
// 8 TSL2591 9 TCD1304 10 11

src/helpers/rtc.c

+81-13
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <stdint.h>
2+
#include <time.h>
23

34
#include "../bus/i2c/i2c.h"
45
#include "../bus/uart/uart.h"
@@ -8,24 +9,69 @@
89
#include "light.h"
910
#include "rtc.h"
1011

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.
1352
uint8_t buffer[9];
1453
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
2362

2463
I2C_InitializeIfNot(I2C_BAUD_RATE_100KHZ, I2C_ENABLE_INTERRUPTS);
2564

2665
return I2C_BulkWrite(buffer, 9, DS1307_I2C_DEVICE_ADDRESS);
2766
}
2867

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+
2975
response_t RTC_SetDigit(void) {
3076

3177
uint8_t buffer[2];
@@ -37,20 +83,42 @@ response_t RTC_SetDigit(void) {
3783
return I2C_BulkWrite(buffer, 2, DS1307_I2C_DEVICE_ADDRESS);
3884
}
3985

40-
response_t RTC_GetTime(void) {
86+
response_t RTC_GetTime(uint32_t* unix_timestamp) {
4187

4288
uint8_t buffer[7];
89+
struct tm tm_info;
4390

4491
I2C_InitializeIfNot(I2C_BAUD_RATE_100KHZ, I2C_ENABLE_INTERRUPTS);
4592

4693
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;
49108
} else return FAILED;
50109

51110
return SUCCESS;
52111
}
53112

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+
54122
response_t RTC_GetDigit(void) {
55123

56124
uint8_t buffer[1];

src/helpers/rtc.h

+32-4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define RTC_H
33

44
#include <xc.h>
5+
#include "../commands.h"
56

67
#define DS1307_I2C_DEVICE_ADDRESS 0x68
78

@@ -60,11 +61,26 @@ extern "C" {
6061
* | OUT (1) | XX (2) | SQWE (1) | XX (2) | RS1:0 (2) |
6162
*
6263
* This method does not pass any messages over the serial back to host.
64+
* This method decodes the unix_timestamp passed as param, converts it into RTC format and
65+
* stores the value in RTC hardware.
66+
*
67+
* @Param
68+
* const* const unix_timestamp: Time to be stored in 32 bit unix timestamp format.
6369
*
6470
* @return SUCCESS, FAILED
6571
*/
66-
response_t RTC_SetTime(void);
67-
72+
response_t RTC_SetTime(uint32_t const* const unix_timestamp);
73+
74+
/**
75+
* @brief Stores time in RTC Hardware.
76+
*
77+
* @description This method reads 32 bit unix timestamp unsigned integer from the host and
78+
* stores the value in RTC Hardware by calling RTC_SetTime function.
79+
*
80+
* @return SUCCESS, FAILED
81+
*/
82+
response_t RTC_CmdSetTime(void);
83+
6884
/**
6985
* @brief Updates a single time parameter in DS1307 real-time clock
7086
*
@@ -94,11 +110,23 @@ extern "C" {
94110
*
95111
* This method will pass 8 unsigned bytes to the host over serial and host
96112
* will need to read all 7 bytes to complete the transaction.
113+
*
114+
* @param
115+
* *unix_timestamp - Time in RTC hardware is converted to unix_timestamp and stored in the parameter
97116
*
98117
* @return SUCCESS, FAILED
99118
*/
100-
response_t RTC_GetTime(void);
101-
119+
response_t RTC_GetTime(uint32_t* unix_timestamp);
120+
121+
/**
122+
* @Brief Fetches time from RTC Hardware in unix_timestamp format.
123+
*
124+
* @Description This method reads time from RTC Hardware and returns the value in unix_timestamp
125+
* format by calling the RTC_GetTime function.
126+
*
127+
* @return SUCCESS, FAILED
128+
*/
129+
response_t RTC_CmdGetTime(void);
102130
/**
103131
* @brief Fetch a single time parameter from DS1307 real-time clock
104132
*

src/sdcard/fatfs/ff_time.c

+17-13
Original file line numberDiff line numberDiff line change
@@ -59,23 +59,27 @@
5959
*/
6060

6161
#include "ff.h"
62+
#include <time.h>
6263
#include <stdint.h>
64+
#include "../../helpers/rtc.h"
65+
66+
DWORD get_fattime (void){
67+
68+
uint32_t unix_timestamp = 0;
69+
RTC_GetTime(&unix_timestamp);
70+
struct tm *tm_info;
71+
72+
time_t timestamp = (time_t) (unix_timestamp);
73+
tm_info = gmtime(&timestamp);
6374

64-
static DWORD decimalToFatTime(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t seconds)
65-
{
6675
DWORD fatTime;
6776

68-
fatTime = (seconds >> 1);
69-
fatTime |= ( ((DWORD)minute) << 5 );
70-
fatTime |= ( ((DWORD)hour) << 11 );
71-
fatTime |= ( ((DWORD)day) << 16 );
72-
fatTime |= ( ((DWORD)month) << 21 );
73-
fatTime |= ( ((DWORD)(year - 1980)) << 25 );
77+
fatTime = (tm_info->tm_sec >> 1);
78+
fatTime |= ( ((DWORD)tm_info->tm_min) << 5 );
79+
fatTime |= ( ((DWORD)tm_info->tm_hour) << 11 );
80+
fatTime |= ( ((DWORD)tm_info->tm_mday) << 16 );
81+
fatTime |= ( ((DWORD)tm_info->tm_mon + 1) << 21 );
82+
fatTime |= ( ((DWORD)(tm_info->tm_year - 80)) << 25 );
7483

7584
return fatTime;
7685
}
77-
78-
DWORD get_fattime (void)
79-
{
80-
return decimalToFatTime(2018, 6, 31, 5, 10, 30);
81-
}

0 commit comments

Comments
 (0)