CLEON  Version 1
Cloud-Offloaded GPS Receiver
hal_rtc.c
Go to the documentation of this file.
1 
7 #include "cleon_conf.h"
8 #include "app_define.h"
9 #include "sys_define.h"
10 #include "hal_define.h"
11 #include "fs_define.h"
12 
13 #define GPS_TEST_ON_INITIALIZATION _ENABLE_
14 
15 // CLEON data structure
19 
20 // Flags
22 extern bool bFLAG_ISLoggingRequested;
26 
27 // Variable for storing SYSRSTIV
28 extern volatile unsigned int SysRstIv;
29 
30 // User parameters
31 extern unsigned long ulSampleCount;
32 extern unsigned long ulSampleGap;
33 extern unsigned long ulChunkCount;
34 extern unsigned long ulChunkGap;
35 
36 // RTC time
38 
39 // Second and millisecond time tick
42 
43 // Counting number of seconds
44 unsigned char ucRTCNumberOfSecondCounter = 0;
45 
46 // Measuring time taken by each step of CLEON data logging
48 
49 /*----------------------------------------------------------------------------*/
58 {
59  // Check if reset has been occured by SVSH(POR)
60  if((SysRstIv == 0x0E)||(SysRstIv == 0x02)){
61  // Restore previous setting
62  RTCCTL01 |= RTCRDYIE; // enable rtc ready interrupt; 1sec
63  RTCCTL01 &= ~RTCHOLD; // release rtchold, begin count
64  // Restore time tick
66  }else{
67  RTCCTL01 |= RTCHOLD; // hold rtc for setting;
68  RTCCTL01 |= RTCRDYIE; // enable rtc ready interrupt; 1sec
69 
70  // Example RTC setting
71  RTCYEAR = 1980; // Year = 1980
72  RTCMON = 1; // Month = 1 (Jan)
73  RTCDAY = 1; // Day = 1 (1st)
74  RTCHOUR = 0; // Hour = 0
75  RTCMIN = 0; // Minute = 0
76  RTCSEC = 0; // Seconds = 0
77 
78  RTCCTL01 &= ~RTCHOLD; // release rtchold, begin count
79 
80  // Indicating that system time is not synchronized
82  }
83 
84  // Change backup system's power source from backup battery to main power
85  while(BAKCTL & LOCKBAK) BAKCTL &= ~(LOCKBAK);
86 }
87 
88 /*----------------------------------------------------------------------------*/
97 {
98  // Only the value of 'Current-year - 1980' will be stored to 'ucYear' field to save memory
99  uniRTCTime.stRTCTime.ucYear = (unsigned char) (HAL_GetRTCYear() - 1980);
100  uniRTCTime.stRTCTime.ucMonth = (unsigned char) HAL_GetRTCMon();
101  uniRTCTime.stRTCTime.ucDay = (unsigned char) HAL_GetRTCDay();
102  uniRTCTime.stRTCTime.ucHour = (unsigned char) HAL_GetRTCHour();
103  uniRTCTime.stRTCTime.ucMinute = (unsigned char) HAL_GetRTCMin();
104  uniRTCTime.stRTCTime.ucSecond = HAL_GetRTCSec();
106 }
107 
108 /*----------------------------------------------------------------------------*/
117 {
118  // Temporary variables
119  rtc_time_u uniTempRTCTime;
120  seoncd_time_tick_u uniTempSecondTimeTick;
121 
122  // Storing time difference
123  unsigned long long ullRTCTimeDifferenceConvertedToTimeTick = 0;
124 
125  // Read stored time information, which was written to FLASH when time was synchronized
126  memcpy(&uniTempRTCTime, (unsigned char *)MSP430_INTERNAL_FLASH_BANK3_ADDRESS, sizeof(uniTempRTCTime));
127  memcpy(&uniTempSecondTimeTick, (unsigned char *)(MSP430_INTERNAL_FLASH_BANK3_ADDRESS + sizeof(uniTempRTCTime)), sizeof(uniTempSecondTimeTick));
128 
129  // Read RTC time
131 
132  // Validity check for restored time tick
133  if(uniRTCTime.stRTCTime.ucYear < 32){
134  // Note that 'uniRTCTime.stRTCTime.ucYear = 0' means current year of RTC is set to 1980 (See, HAL_RTC_ReadRTCTime())
135  // Because this source is being written in year of 2012, 'ucYear' cannot be smaller than 32 (2012 - 1980 = 32)
136  // If uniRTCTime.stRTCTime.ucYear is equal to zero, it means that current system RTC time has neither been synchronized nor restored correctly
138  }else{
139  // If it is confirmed that RTC has been running even for the period of main-battery-failure, then, get current time tick out of RTC time
140  // First, we get total seconds out of both current and stored RTC time
141  // After that, get the differnce in seconds and add it to the previous time tick which has been kept in FLASH from last time synchronization
142  ullRTCTimeDifferenceConvertedToTimeTick = HAL_RTC_GetSecondConvertedFromStoredRTCTime(&uniRTCTime) - HAL_RTC_GetSecondConvertedFromStoredRTCTime(&uniTempRTCTime);
143  uniSecondTimeTick.ullSecondTimeTick = uniTempSecondTimeTick.ullSecondTimeTick + (ullRTCTimeDifferenceConvertedToTimeTick * 10000000);
144 
145  // Set flag
147 
148  // Turn LED3 off
150  }
151 }
152 
153 /*----------------------------------------------------------------------------*/
161 unsigned long long HAL_RTC_GetSecondConvertedFromStoredRTCTime(rtc_time_u *ptruniTempRTCTime)
162 {
163  // Total elapsed time represented in seconds
164  unsigned long long ullConvertedSecond = 0;
165 
166  // Variable for checking leap year
167  bool bIsLeapYear = _FALSE_;
168 
169  // 'ucYear' is regarded as leap year if it is divisible by 4
170  // (See, pp. 567 of 'MSP430x5xx and MSP430x6xx Family User's Guide)
171  if(ptruniTempRTCTime->stRTCTime.ucYear % 4 == 0) bIsLeapYear = _TRUE_;
172 
173  // Get total elapsed seconds from the first day of year 1 to the first day of RTC year
174  ullConvertedSecond += (ptruniTempRTCTime->stRTCTime.ucYear - 1) * 365 * 24 * 60 * 60;
175  // Compansate days in leap years
176  ullConvertedSecond += (ptruniTempRTCTime->stRTCTime.ucYear / 4);
177 
178  // Get total elapsed seconds from the first day of this year to the end of previous month of RTC month
179  switch(ptruniTempRTCTime->stRTCTime.ucMonth){
180  case 1: // Jan
181  ullConvertedSecond += (unsigned long long)DAYS_IN_MONTHS_BEFORE_THE_FIRST_DAY_OF_JAN * 24 * 60 * 60;
182  break;
183  case 2: // Feb
184  ullConvertedSecond += (unsigned long long)DAYS_IN_MONTHS_BEFORE_THE_FIRST_DAY_OF_FEB * 24 * 60 * 60;
185  break;
186  case 3: // Mar
187  ullConvertedSecond += (unsigned long long)DAYS_IN_MONTHS_BEFORE_THE_FIRST_DAY_OF_MAR * 24 * 60 * 60;
188  break;
189  case 4: // Apr
190  ullConvertedSecond += (unsigned long long)DAYS_IN_MONTHS_BEFORE_THE_FIRST_DAY_OF_APR * 24 * 60 * 60;
191  break;
192  case 5: // May
193  ullConvertedSecond += (unsigned long long)DAYS_IN_MONTHS_BEFORE_THE_FIRST_DAY_OF_MAY * 24 * 60 * 60;
194  break;
195  case 6: // Jun
196  ullConvertedSecond += (unsigned long long)DAYS_IN_MONTHS_BEFORE_THE_FIRST_DAY_OF_JUN * 24 * 60 * 60;
197  break;
198  case 7: // Jul
199  ullConvertedSecond += (unsigned long long)DAYS_IN_MONTHS_BEFORE_THE_FIRST_DAY_OF_JUL * 24 * 60 * 60;
200  break;
201  case 8: // Aug
202  ullConvertedSecond += (unsigned long long)DAYS_IN_MONTHS_BEFORE_THE_FIRST_DAY_OF_AUG * 24 * 60 * 60;
203  break;
204  case 9: // Sep
205  ullConvertedSecond += (unsigned long long)DAYS_IN_MONTHS_BEFORE_THE_FIRST_DAY_OF_SEP * 24 * 60 * 60;
206  break;
207  case 10:// Oct
208  ullConvertedSecond += (unsigned long long)DAYS_IN_MONTHS_BEFORE_THE_FIRST_DAY_OF_OCT * 24 * 60 * 60;
209  break;
210  case 11:// Nov
211  ullConvertedSecond += (unsigned long long)DAYS_IN_MONTHS_BEFORE_THE_FIRST_DAY_OF_NOV * 24 * 60 * 60;
212  break;
213  case 12:// Dec
214  ullConvertedSecond += (unsigned long long)DAYS_IN_MONTHS_BEFORE_THE_FIRST_DAY_OF_DEC * 24 * 60 * 60;
215  break;
216  default:
217  break;
218  }
219 
220  // If it is leap year, add one day
221  if((bIsLeapYear == _TRUE_)&&(ptruniTempRTCTime->stRTCTime.ucMonth != 1)){
222  ullConvertedSecond += (long long)24 * 60 * 60;
223  }
224 
225  ullConvertedSecond += ((ptruniTempRTCTime->stRTCTime.ucDay)-1) * 24 * 60 * 60;
226  ullConvertedSecond += ((ptruniTempRTCTime->stRTCTime.ucHour)-1) * 60 * 60;
227  ullConvertedSecond += ((ptruniTempRTCTime->stRTCTime.ucMinute)-1) * 60;
228  ullConvertedSecond += ptruniTempRTCTime->stRTCTime.ucSecond;
229 
230  // Total elapsed time from the first day of year 1, which is represented in seconds
231  return ullConvertedSecond;
232 }
233 
234 //------------------------------------------------------------------------------
235 // RTC Interrupt Service Routine
236 //------------------------------------------------------------------------------
237 #pragma vector=RTC_VECTOR
238 __interrupt void RTC_VECTOR_ISR(void)
239 {
240  switch(__even_in_range(RTCIV,16))
241  {
242  case RTC_NONE: // No interrupts
243  break;
244  case RTC_RTCRDYIFG: // RTCRDYIFG
246 
247  // Reset millisecond to zero
248  uniMillisecondTimeTick.ullMillisecondTimeTick = 0;
249 
250  // Increase second time tick
251  uniSecondTimeTick.ullSecondTimeTick += 10000000;
252 
253  // Set flag if condition is met
255  if(ulSampleCount != 1){
256  // Check if defined time interval for logging has elapsed
257  if(ucRTCNumberOfSecondCounter == ((ulSampleGap/1000)-1)){
260  // If defined time interval for logging has elapsed, exit low-power-mode
261  __low_power_mode_off_on_exit();
262  }else{
265  }
266  }
267  }
268  }
269  break;
270  case RTC_RTCTEVIFG: // RTCEVIFG
271  break;
272  case RTC_RTCAIFG: // RTCAIFG
273  break;
274  case RTC_RT0PSIFG: // RT0PSIFG
275  break;
276  case RTC_RT1PSIFG: // RT1PSIFG
277  break;
278  case 12: break; // Reserved
279  case 14: break; // Reserved
280  case 16: break; // Reserved
281  default: break;
282  }
283 }
284 
286 unsigned int HAL_SetRTCYear(int year)
287 {
288  RTCYEAR = year;
289  return year;
290 }
291 
292 unsigned int HAL_SetRTCMon(int month)
293 {
294  RTCMON = month;
295  return month;
296 }
297 
298 unsigned int HAL_SetRTCDay(int day)
299 {
300  RTCDAY = day;
301  return day;
302 }
303 
304 unsigned int HAL_SetRTCDow(int dow)
305 {
306  RTCDOW = dow;
307  return dow;
308 }
309 
310 unsigned int HAL_SetRTCHour(int hour)
311 {
312  RTCHOUR = hour;
313  return hour;
314 }
315 
316 unsigned int HAL_SetRTCMin(int min)
317 {
318  RTCMIN = min;
319  return min;
320 }
321 
322 unsigned int HAL_SetRTCSec(int sec)
323 {
324  RTCSEC = sec;
325  return sec;
326 }
327 
328 unsigned int HAL_SetRTCMilisec(int millisec)
329 {
330  uniRTCTime.stRTCTime.uiMillisecond = uniMillisecondTimeTick.ullMillisecondTimeTick/10000;
331  return (uniRTCTime.stRTCTime.uiMillisecond);
332 }
333 
335 unsigned int HAL_GetRTCYear(void)
336 {
337  return RTCYEAR;
338 }
339 
340 unsigned int HAL_GetRTCMon(void)
341 {
342  return RTCMON;
343 }
344 
345 unsigned int HAL_GetRTCDow(void)
346 {
347  return RTCDOW;
348 }
349 
350 unsigned int HAL_GetRTCDay(void)
351 {
352  return RTCDAY;
353 }
354 
355 unsigned int HAL_GetRTCHour(void)
356 {
357  return RTCHOUR;
358 }
359 
360 unsigned int HAL_GetRTCMin(void)
361 {
362  return RTCMIN;
363 }
364 
365 unsigned int HAL_GetRTCSec(void)
366 {
367  return RTCSEC;
368 }
369 
370 unsigned int HAL_GetRTCMilisec(void)
371 {
372  unsigned int uiTemp = 0;
373  uiTemp = (unsigned int)(uniMillisecondTimeTick.ullMillisecondTimeTick/10000);
374 
375  if(uiTemp > 999) uiTemp = 0; // set value of ullMillisecondTick to 0, if it exceeds 999, to correct 1ms error
376  return uiTemp;
377 }