blob: 61f263ccfab76600be857e6eeee4c47518f2996c [file] [log] [blame]
zongqiang.zhang0c6a0882019-08-07 14:48:21 +08001#include "rtc.h"
2#include "time.h"
3#include "data_tools.h"
4#include "string.h"
5#include "timer.h"
6
7uint32_t CrystalStartErrFlag;
8
9static uint8_t rtc_wait_flag(uint32_t* reg, uint32_t mask, uint32_t flag, uint32_t timeout)
10{
11 uint32_t t = timeout/100;
12
13 while(((*reg)&mask) != flag)
14 {
15 delay_ms(100);
16 t --;
17 if(t == 0)
18 return 1;
19 }
20
21 return 0;
22}
23
24uint32_t rtc_get_counter(void)
25{
26 return (uint32_t)((RTC->CNTH << 16) | RTC->CNTL);
27}
28
29static uint8_t rtc_set_counter(uint32_t cnt)
30{
31 PWR->CR |= PWR_CR_DBP; // ʹÄÜ·ÃÎÊRTC, BDC ¼Ä´æÆ÷
32 RTC->CRL |=RTC_CRL_CNF; // ÉèÖÃRTCÅäÖñê¼Ç,ÔÊÐíÅäÖÃ
33 RTC->CNTH = (cnt>>16)&0xffff;
34 RTC->CNTL = cnt&0xffff ;
35 RTC->CRL &= ~RTC_CRL_CNF; // ÉèÖÃRTCÅäÖñê¼Ç,²»ÔÊÐíÅäÖÃ
36 if(rtc_wait_flag((uint32_t*)&RTC->CRL, RTC_FLAG_RTOFF, RTC_FLAG_RTOFF, 4000ul)) //µÈ´ýÅäÖÃÍê³É
37 {
38 PWR->CR &= ~PWR_CR_DBP; // ²»ÔÊÐíÅäÖÃRTC¡¢BDC¼Ä´æÆ÷
39 return 1;
40 }
41 PWR->CR &= ~PWR_CR_DBP; // ²»ÔÊÐíÅäÖÃRTC¡¢BDC¼Ä´æÆ÷
42 return 0;
43}
44
45void rtc_init(void)
46{
47 CrystalStartErrFlag = 0;
48 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
49
50 //RTCÊ×´ÎÉϵç»òʱÖÓ¶ªÊ§
51 if(BKP_ReadBackupRegister(BKP_DR1) != 0x5A5A)
52 {
53 RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE);
54 PWR_BackupAccessCmd(ENABLE);
55 BKP_DeInit();
56 RCC_LSEConfig(RCC_LSE_ON);
57
58 //²ÎÕÕstm32f10x datasheet£¬LES startup time
59 //tsu(lse) = 3S (Typ)
60 //´Ë´¦µÈ´ýLSEÆðÕñÑÓʱԼ4S
61 if(rtc_wait_flag((uint32_t*)&RCC->BDCR, 0x02, 0x02, 4000ul))
62 CrystalStartErrFlag = 1;
63
64 if(!CrystalStartErrFlag)
65 {
66 RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
67 RCC_RTCCLKCmd(ENABLE);
68 /* Clear RSF flag */
69 RTC->CRL &= (u16)~RTC_FLAG_RSF;
70 /* Loop until RSF flag is set */
71 if(rtc_wait_flag((uint32_t*)&RTC->CRL, RTC_FLAG_RSF, RTC_FLAG_RSF, 4000ul))
72 CrystalStartErrFlag = 1;
73
74 //rtc wait for last task
75 if(rtc_wait_flag((uint32_t*)&RTC->CRL, RTC_FLAG_RTOFF, RTC_FLAG_RTOFF, 4000ul))
76 CrystalStartErrFlag = 1;
77
78 RTC_SetPrescaler(32767);
79 //rtc wait for last task
80 if(rtc_wait_flag((uint32_t*)&RTC->CRL, RTC_FLAG_RTOFF, RTC_FLAG_RTOFF, 4000ul))
81 CrystalStartErrFlag = 1;
82
83 BKP_WriteBackupRegister(BKP_DR1, 0x5A5A);
84 }
85 PWR_BackupAccessCmd(DISABLE);
86 RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, DISABLE);
87 }
88 else
89 {
90 /* Clear RSF flag */
91 RTC->CRL &= (u16)~RTC_FLAG_RSF;
92 /* Loop until RSF flag is set */
93 if(rtc_wait_flag((uint32_t*)&RTC->CRL, RTC_FLAG_RSF, RTC_FLAG_RSF, 4000ul))
94 CrystalStartErrFlag = 1;
95 else
96 {
97 //0x386D4380ul 2000Äê1ÔÂ1ÈÕÃëÊý
98 if(rtc_get_counter()<0x386D4380ul)
99 {
100 rtc_set_counter(0x386D4380ul);
101 }
102
103// rtc_get_time(&SystemTime);
104 }
105 }
106}
107
108uint32_t rtc_mk_time(_SystemTime* t)
109{
110 struct tm temp_time;
111 _SystemTime temp_time_hex;
112
113 memcpy(&temp_time_hex, t, sizeof(_SystemTime));
114 bcd2hex(&temp_time_hex, sizeof(temp_time_hex));
115 temp_time.tm_year = temp_time_hex.year+100; //´Ó1900Ä꿪ʼ
116 temp_time.tm_mon = temp_time_hex.month-1;
117 temp_time.tm_mday = temp_time_hex.day;
118 temp_time.tm_wday = temp_time_hex.week;
119 temp_time.tm_hour = temp_time_hex.hour;
120 temp_time.tm_min = temp_time_hex.minute;
121 temp_time.tm_sec = temp_time_hex.second;
122
123 return mktime(&temp_time);
124}
125
126uint8_t rtc_set_time(_SystemTime* t)
127{
128 uint8_t ret = 0;
129 time_t seconds = rtc_mk_time(t);
130
131 ret = rtc_set_counter(seconds);
132
133 return ret;
134}
135
136uint8_t rtc_get_time(_SystemTime* t)
137{
138 struct tm* temp_time;
139 _SystemTime temp_time_bcd;
140 time_t seconds = rtc_get_counter();
141
142 temp_time = localtime(&seconds);
143 if(temp_time->tm_year<100)
144 temp_time_bcd.year = 0;
145 else
146 temp_time_bcd.year = temp_time->tm_year - 100;
147
148 temp_time_bcd.month = temp_time->tm_mon+1;
149 temp_time_bcd.day = temp_time->tm_mday;
150 temp_time_bcd.week = temp_time->tm_wday;
151 temp_time_bcd.hour = temp_time->tm_hour;
152 temp_time_bcd.minute = temp_time->tm_min;
153 temp_time_bcd.second = temp_time->tm_sec;
154 hex2bcd(&temp_time_bcd, sizeof(temp_time_bcd));
155 memcpy(t, &temp_time_bcd, sizeof(temp_time_bcd));
156 return 0;
157}
158
159uint32_t rtc_time_diff(void* t1, void* t2)
160{
161 uint32_t t1_sec = rtc_mk_time((_SystemTime*)t1);
162 uint32_t t2_sec = rtc_mk_time((_SystemTime*)t2);
163
164 return (t1_sec-t2_sec);
165}