1 /*
2 * Copyright (c) 2022 OpenLuat & AirM2M
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy of
5 * this software and associated documentation files (the "Software"), to deal in
6 * the Software without restriction, including without limitation the rights to
7 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8 * the Software, and to permit persons to whom the Software is furnished to do so,
9 * subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in all
12 * copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 */
21
22 #include "user.h"
23
RTC_DummyCB(void * pData,void * pParam)24 static int32_t RTC_DummyCB(void *pData, void *pParam)
25 {
26 DBG("!");
27 return 0;
28 }
29
30 static CBFuncEx_t prvRTCCB;
31 static void *prvParam;
32
RTC_IrqHandler(int32_t Line,void * pData)33 static void RTC_IrqHandler(int32_t Line, void *pData)
34 {
35 RTC->RTC_INTCLR = 1;
36 ISR_OnOff(RTC_IRQn, 0);
37 prvRTCCB(pData, prvParam);
38 }
39
RTC_GlobalInit(void)40 void RTC_GlobalInit(void)
41 {
42 int8_t Buf[4][6];
43 LongInt Tamp;
44 char *strMon[12] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
45 int Day,Year,Mon,Hour,Min,Sec,i;
46 CmdParam CP;
47 Date_UserDataStruct BuildDate;
48 Time_UserDataStruct BuildTime;
49 prvRTCCB = RTC_DummyCB;
50 if (!RTC->RTC_REF)
51 {
52 DBG("rtc lost power!");
53 memset(&CP, 0, sizeof(CP));
54 memset(Buf, 0, sizeof(Buf));
55 CP.param_max_len = 6;
56 CP.param_max_num = 4;
57 CP.param_str = (int8_t *)Buf;
58 CmdParseParam(__DATE__, &CP, ' ');
59 Mon = 0;
60 for (i = 0; i < 12; i++)
61 {
62 if (!strcmp(strMon[i], Buf[0]))
63 {
64 Mon = i + 1;
65 }
66 }
67
68 if (Buf[1][0])
69 {
70 Day = strtol(Buf[1], NULL, 10);
71 Year = strtol(Buf[2], NULL, 10);
72 }
73 else
74 {
75 Day = strtol(Buf[2], NULL, 10);
76 Year = strtol(Buf[3], NULL, 10);
77 }
78
79
80 CP.param_num = 0;
81 memset(Buf, 0, sizeof(Buf));
82
83 CP.param_str = (int8_t *)Buf;
84 CmdParseParam(__TIME__, &CP, ':');
85 Hour = strtol(Buf[0], NULL, 10);
86 Min = strtol(Buf[1], NULL, 10);
87 Sec = strtol(Buf[2], NULL, 10);
88 BuildDate.Year = Year;
89 BuildDate.Mon = Mon;
90 BuildDate.Day = Day;
91 BuildTime.Hour = Hour;
92 BuildTime.Min = Min;
93 BuildTime.Sec = Sec;
94 RTC_SetDateTime(&BuildDate, &BuildTime, 0);
95 }
96 #ifdef __BUILD_OS__
97 ISR_SetPriority(RTC_IRQn, IRQ_MAX_PRIORITY + 1);
98 #else
99 ISR_SetPriority(RTC_IRQn, 3);
100 #endif
101 ISR_SetHandler(RTC_IRQn, RTC_IrqHandler, NULL);
102 // RTC_GetDateTime(&uBuildDate, &uBuildTime);
103 // DBG("%04u-%02u-%02u %02u:%02u:%02u", uBuildDate.Date.Year, uBuildDate.Date.Mon,
104 // uBuildDate.Date.Day, uBuildTime.Time.Hour, uBuildTime.Time.Min,
105 // uBuildTime.Time.Sec);
106
107 }
108
RTC_SetStamp(uint32_t Stamp)109 void RTC_SetStamp(uint32_t Stamp)
110 {
111 while (!(RTC->RTC_CS & RTC_CS_READY)) {;}
112 RTC->RTC_CS |= RTC_CS_CLR;
113 while (RTC->RTC_CS & RTC_CS_CLR) {;}
114 RTC->RTC_REF = Stamp;
115 }
116
RTC_SetDateTime(Date_UserDataStruct * pDate,Time_UserDataStruct * pTime,uint8_t isForce)117 void RTC_SetDateTime(Date_UserDataStruct *pDate, Time_UserDataStruct *pTime, uint8_t isForce)
118 {
119 uint64_t Tamp = UTC2Tamp(pDate, pTime);
120 uint32_t curTime;
121 uint32_t newTime = (uint32_t)Tamp;
122 while (!(RTC->RTC_CS & RTC_CS_READY)) {;}
123 if (isForce)
124 {
125 RTC->RTC_CS |= RTC_CS_CLR;
126 while (RTC->RTC_CS & RTC_CS_CLR) {;}
127 RTC->RTC_REF = newTime;
128 }
129 else
130 {
131 RTC->RTC_CS |= RTC_CS_LOCK_TIM;
132 curTime = RTC->RTC_TIM;
133 RTC->RTC_CS &= ~RTC_CS_LOCK_TIM;
134 curTime += RTC->RTC_REF;
135 if (newTime > curTime)
136 {
137 RTC->RTC_CS |= RTC_CS_CLR;
138 while (RTC->RTC_CS & RTC_CS_CLR) {;}
139 RTC->RTC_REF = newTime;
140 }
141 }
142 }
143
RTC_GetDateTime(Date_UserDataStruct * pDate,Time_UserDataStruct * pTime)144 void RTC_GetDateTime(Date_UserDataStruct *pDate, Time_UserDataStruct *pTime)
145 {
146 Tamp2UTC(RTC_GetUTC(), pDate, pTime, 0);
147 }
148
RTC_GetUTC(void)149 uint64_t RTC_GetUTC(void)
150 {
151 uint64_t curTime;
152 while (!(RTC->RTC_CS & RTC_CS_READY)) {;}
153 RTC->RTC_CS |= RTC_CS_LOCK_TIM;
154 curTime = RTC->RTC_TIM;
155 RTC->RTC_CS &= ~RTC_CS_LOCK_TIM;
156 curTime += RTC->RTC_REF;
157 return curTime;
158 }
159
RTC_SetAlarm(uint32_t TimeSecond,CBFuncEx_t CB,void * pParam)160 void RTC_SetAlarm(uint32_t TimeSecond, CBFuncEx_t CB, void *pParam)
161 {
162 while (!(RTC->RTC_CS & RTC_CS_READY)) {;}
163 RTC->RTC_INTCLR = 1;
164 RTC->RTC_CS &= ~RTC_CS_ALARM_EN;
165 RTC->RTC_CS |= RTC_CS_LOCK_TIM;
166 RTC->RTC_ARM = RTC->RTC_TIM + TimeSecond;
167 RTC->RTC_CS &= ~RTC_CS_LOCK_TIM;
168 if (CB)
169 {
170 prvRTCCB = CB;
171 }
172 else
173 {
174 prvRTCCB = RTC_DummyCB;
175 }
176 prvParam = pParam;
177 RTC->RTC_CS |= RTC_CS_ALARM_EN;
178 ISR_OnOff(RTC_IRQn, 1);
179 }
180