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