Skip to content

Commit fbe6264

Browse files
authored
Rewrite the RTClock library.
1 parent 47c94bc commit fbe6264

File tree

2 files changed

+157
-20
lines changed

2 files changed

+157
-20
lines changed

STM32F1/libraries/RTClock/src/RTClock.cpp

Lines changed: 101 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -81,21 +81,108 @@
8181
*/
8282

8383
void RTClock::setTime (time_t time_stamp) {
84-
rtc_set_count(time_stamp);
84+
breakTime(time_stamp, tmm); // time will be broken to tm
85+
setTime(tmm);
86+
//rtc_set_count(time_stamp);
8587
}
8688

87-
void RTClock::setTime (struct tm* tm_ptr) {
88-
rtc_set_count(mktime (tm_ptr));
89-
}
89+
#define LEAP_YEAR(Y) ( ((1970+Y)>0) && !((1970+Y)%4) && ( ((1970+Y)%100) || !((1970+Y)%400) ) )
9090

91+
//-----------------------------------------------------------------------------
92+
void RTClock::breakTime(time_t timeInput, tm_t & tmm)
93+
{
94+
// break the given time_t into time components
95+
// this is a more compact version of the C library localtime function
96+
// note that year is offset from 1970 !!!
97+
98+
uint8_t year;
99+
uint8_t month, monthLength;
100+
uint32_t time;
101+
uint32_t days;
102+
103+
time = (uint32_t)timeInput;
104+
tmm.second = time % 60;
105+
time /= 60; // now it is minutes
106+
tmm.minute = time % 60;
107+
time /= 60; // now it is hours
108+
tmm.hour = time % 24;
109+
time /= 24; // now it is days
110+
tmm.weekday = ((time + 4) % 7); // Monday is day 1 // + 1; // Sunday is day 1
111+
112+
year = 0;
113+
days = 0;
114+
while((unsigned)(days += (LEAP_YEAR(year) ? 366 : 365)) <= time) {
115+
year++;
116+
}
117+
tmm.year = year; // year is offset from 1970
118+
119+
days -= LEAP_YEAR(year) ? 366 : 365;
120+
time -= days; // now it is days in this year, starting at 0
121+
122+
days = 0;
123+
month = 0;
124+
monthLength = 0;
125+
for (month=0; month<12; month++) {
126+
if (month==1) { // february
127+
if (LEAP_YEAR(year)) {
128+
monthLength=29;
129+
} else {
130+
monthLength=28;
131+
}
132+
} else {
133+
monthLength = monthDays[month];
134+
}
135+
136+
if (time >= monthLength) {
137+
time -= monthLength;
138+
} else {
139+
break;
140+
}
141+
}
142+
tmm.month = month + 1; // jan is month 1
143+
tmm.day = time + 1; // day of month
144+
}
145+
146+
//-----------------------------------------------------------------------------
147+
time_t RTClock::makeTime(tm_t & tmm)
148+
{
149+
// assemble time elements into time_t
150+
// note year argument is offset from 1970 (see macros in time.h to convert to other formats)
151+
// previous version used full four digit year (or digits since 2000),i.e. 2009 was 2009 or 9
152+
153+
int i;
154+
uint32_t seconds;
155+
156+
// seconds from 1970 till 1 jan 00:00:00 of the given year
157+
seconds = tmm.year*(SECS_PER_DAY * 365);
158+
for (i = 0; i < tmm.year; i++) {
159+
if (LEAP_YEAR(i)) {
160+
seconds += SECS_PER_DAY; // add extra days for leap years
161+
}
162+
}
163+
164+
// add days for this year, months start from 1
165+
for (i = 1; i < tmm.month; i++) {
166+
if ( (i == 2) && LEAP_YEAR(tmm.year)) {
167+
seconds += SECS_PER_DAY * 29;
168+
} else {
169+
seconds += SECS_PER_DAY * monthDays[i-1]; //monthDay array starts from 0
170+
}
171+
}
172+
seconds+= (tmm.day-1) * SECS_PER_DAY;
173+
seconds+= tmm.hour * SECS_PER_HOUR;
174+
seconds+= tmm.minute * SECS_PER_MIN;
175+
seconds+= tmm.second;
176+
return (time_t)seconds;
177+
}
178+
91179
time_t RTClock::getTime() {
92180
return rtc_get_count();
93181
}
94-
95-
struct tm* RTClock::getTime(struct tm* tm_ptr) {
182+
183+
void RTClock::getTime(tm_t & tm_ptr) {
96184
time_t res = rtc_get_count();
97-
tm_ptr = gmtime(&res); //why not gmtime?
98-
return tm_ptr;
185+
breakTime(res, tm_ptr);
99186
}
100187

101188
void RTClock::createAlarm(voidFuncPtr function, time_t alarm_time_t) {
@@ -110,15 +197,16 @@
110197
rtc_detach_interrupt(RTC_SECONDS_INTERRUPT);
111198
}
112199

113-
114-
void RTClock::createAlarm(voidFuncPtr function, tm* alarm_tm) {
115-
time_t alarm = mktime(alarm_tm);//convert to time_t
200+
201+
void RTClock::createAlarm(voidFuncPtr function, tm_t & alarm_tm) {
202+
time_t alarm = makeTime(alarm_tm);//convert to time_t
116203
createAlarm(function, alarm);
117204
}
118205

119206
//change alarm time
120-
void RTClock::setAlarmTime (tm * tm_ptr) {
121-
time_t time = mktime(tm_ptr);//convert to time_t
207+
208+
void RTClock::setAlarmTime (tm_t & tm_ptr) {
209+
time_t time = makeTime(tm_ptr);//convert to time_t
122210
rtc_set_alarm(time); //must be int... for standardization sake.
123211
}
124212

STM32F1/libraries/RTClock/src/RTClock.h

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,35 @@
77
#ifndef _RTCLOCK_H_
88
#define _RTCLOCK_H_
99

10+
#define SECS_PER_MIN (60UL)
11+
#define SECS_PER_HOUR (3600UL)
12+
#define SECS_PER_DAY (SECS_PER_HOUR * 24UL)
13+
#define DAYS_PER_WEEK (7UL)
14+
#define SECS_PER_WEEK (SECS_PER_DAY * DAYS_PER_WEEK)
15+
#define SECS_PER_YEAR (SECS_PER_WEEK * 52UL)
16+
#define SECS_YR_2000 (946684800UL) // the time at the start of y2k
17+
#define LEAP_YEAR(Y) ( ((1970+Y)>0) && !((1970+Y)%4) && ( ((1970+Y)%100) || !((1970+Y)%400) ) )
1018

19+
#if !defined(__time_t_defined) // avoid conflict with newlib or other posix libc
20+
#warning "Using private time_t definintion"
21+
typedef uint32_t time_t;
22+
#endif
1123

24+
static const unsigned char monthDays[]={31,28,31,30,31,30,31,31,30,31,30,31}; // API starts months from 1, this array starts from 0
1225

26+
typedef struct tm_t {
27+
uint8_t year; // years since 1970
28+
uint8_t month; // month of a year - [ 1 to 12 ]
29+
uint8_t day; // day of a month - [ 1 to 31 ]
30+
uint8_t weekday; // day of a week (first day is Sunday) - [ 0 to 6 ]
31+
uint8_t pm; // AM: 0, PM: 1
32+
uint8_t hour; // hour of a day - [ 0 to 23 ]
33+
uint8_t minute; // minute of an hour - [ 0 to 59 ]
34+
uint8_t second; // second of a minute - [ 0 to 59 ]
35+
} tm_t;
36+
37+
static inline uint8_t bcd2bin(uint8_t b) { return ( (10*(b>>4)) + (b&0x0F) ); }
38+
static inline uint8_t bin2bcd(uint8_t b) { return ( ((b/10)<<4) + (b%10) ); }
1339

1440
class RTClock {
1541
public:
@@ -18,24 +44,47 @@ class RTClock {
1844
RTClock(rtc_clk_src src, uint16 prescaler );
1945
//~RTClock(); //to implement
2046

21-
47+
void breakTime(time_t epoch_time, tm_t & tmm);
48+
time_t makeTime(tm_t & tmm);
49+
2250
void setTime (time_t time_stamp);
23-
void setTime (struct tm * tm_ptr);
51+
void setTime (tm_t & tmm);
2452

25-
struct tm* getTime(struct tm* tm_ptr);
2653
time_t getTime();
54+
void getTime(tm_t & tmm );
55+
#define now getTime
56+
57+
uint8_t year(void) { getTime(tmm); return tmm.year; }
58+
uint8_t month(void) { getTime(tmm); return tmm.month; }
59+
uint8_t day(void) { getTime(tmm); return tmm.day; }
60+
uint8_t weekday(void) { getTime(tmm); return tmm.weekday; }
61+
uint8_t hour(void) { getTime(tmm); return tmm.hour; }
62+
uint8_t minute(void) { getTime(tmm); return tmm.minute; }
63+
uint8_t second(void) { getTime(tmm); return tmm.second; }
64+
uint8_t isPM(void) { return ( hour()>=12 ); }
65+
66+
uint8_t year(time_t t) { breakTime(t, tmm); return tmm.year; }
67+
uint8_t month(time_t t) { breakTime(t, tmm); return tmm.month; }
68+
uint8_t day(time_t t) { breakTime(t, tmm); return tmm.day; }
69+
uint8_t weekday(time_t t) { breakTime(t, tmm); return tmm.weekday; }
70+
uint8_t hour(time_t t) { breakTime(t, tmm); return tmm.hour; }
71+
uint8_t minute(time_t t) { breakTime(t, tmm); return tmm.minute; }
72+
uint8_t second(time_t t) { breakTime(t, tmm); return tmm.second; }
73+
uint8_t isPM(time_t t) { return (hour(t)>=12); }
2774

2875
void createAlarm(voidFuncPtr function, time_t alarm_time_t);
29-
void createAlarm(voidFuncPtr function, struct tm* alarm_tm);
76+
void createAlarm(voidFuncPtr function, struct tm_t & alarm_tm);
3077

3178
void attachSecondsInterrupt(voidFuncPtr function);
3279
void detachSecondsInterrupt();
3380

34-
void setAlarmTime (tm * tm_ptr);
81+
void setAlarmTime (tm_t & tm_ptr);
3582
void setAlarmTime (time_t alarm_time);
36-
//private:
83+
84+
85+
tm_t tmm;
86+
};
3787

38-
} ;
3988

4089

4190

0 commit comments

Comments
 (0)