solarium/.svn/pristine/63/63437cfb8210b598b7533626af5f844900a3a406.svn-base
2021-04-15 21:07:13 +03:00

323 lines
8.1 KiB
Plaintext

#include "iolpc2368.h"
#include "ucos_ii.h"
#include "cpu.h"
#include "app_serv.h"
#include "time.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void RTC_Isr (void)
{
CPU_INT32U ilr;
ilr = ILR & 0x7;
if (ilr & 0x1) PostUserEvent(EVENT_SEC);
ILR = ilr;
}
void RTC_ReadTime(TRTC_Data *rtc)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
rtc->sec = SEC;
rtc->min = MIN;
rtc->hour = HOUR;
rtc->day = DOW;
rtc->date = DOM;
rtc->mon = MONTH;
rtc->year = YEAR-2000;
OS_EXIT_CRITICAL();
}
void RTC_SetTime(TRTC_Data *rtc)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
SEC = rtc->sec;
MIN = rtc->min;
HOUR = rtc->hour;
DOW = rtc->day;
DOM = rtc->date;
MONTH = rtc->mon;
YEAR = rtc->year+2000;
OS_EXIT_CRITICAL();
}
extern CPU_INT32U BSP_CPU_PclkFreq (CPU_INT08U pclk);
void InitRTC(void)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
PCONP_bit.PCRTC = 1;
PCLKSEL0_bit.PCLK_RTC = 0;
OS_ENTER_CRITICAL();
CCR = 0x0011;
PREINT = (BSP_CPU_PclkFreq(9) / 32768) - 1;
PREFRAC = BSP_CPU_PclkFreq(9) - ((PREINT + 1) * 32768);
// If year is corrupt, set reasonable date.
if ((YEAR < 2010) || (HOUR > 23) || (YEAR > 2100)) {
CCR = 0x0000;
YEAR = 2010;
MONTH = 8;
DOM = 8;
HOUR = 7;
MIN = 0;
CCR = 0x0011;
}
VICVECTADDR13 = (CPU_INT32U)RTC_Isr;
VICINTSELECT &= ~(1 << VIC_RTC);
VICVECTPRIORITY13 = 7;
VICINTENABLE = (1 << VIC_RTC);
CISS = 0;
AMR = 0xff;
CIIR = 0x1; // sec interrupt
OS_EXIT_CRITICAL();
}
const char str_sunday[] = "ÂÎÑÊÐÅÑÅÍbÅ";
const char str_monday[] = "ÏÎÍÅÄÅËbÍÈÊ";
const char str_tuesday[] = "ÂÒÎÐÍÈÊ";
const char str_wednesday[] = "ÑÐÅÄÀ";
const char str_thirsday[] = "×ÅÒÂÅÐÃ";
const char str_friday[] = "ÏßÒÍÈÖÀ";
const char str_saturday[] = "ÑÓÁÁÎÒÀ";
const char* weekday[]={str_sunday, str_monday, str_tuesday, str_wednesday, str_thirsday, str_friday, str_saturday};
void GetDayText(char* str, char day)
{
strcpy(str, weekday[day]);
}
const char str_jan[] = "ßÍÂÀÐß";
const char str_feb[] = "ÔÅÂÐÀËß";
const char str_mar[] = "ÌÀÐÒÀ";
const char str_apr[] = "ÀÏÐÅËß";
const char str_may[] = "ÌÀß";
const char str_jun[] = "ÈÞÍß";
const char str_jul[] = "ÈÞËß";
const char str_aug[] = "ÀÂÃÓÑÒÀ";
const char str_sep[] = "ÑÅÍÒßÁÐß";
const char str_okt[] = "ÎÊÒßÁÐß";
const char str_nov[] = "ÍÎßÁÐß";
const char str_dec[] = "ÄÅÊÀÁÐß";
const char* month[]={str_jan, str_feb, str_mar, str_apr, str_may, str_jun, str_jul, str_aug, str_sep, str_okt, str_nov, str_dec};
//×èñëî ñåêóíä îò Ðîæäåñòâà Õðèñòîâà äî 1 ÿíâàðÿ 1970
#define JESUS_TO_70 2007437056
//×èñëî ìèíóò îò Ðîæäåñòâà Õðèñòîâà äî 1 ÿíâàðÿ 1970
#define JESUS_TO_70MIN 1035616320
// ×èñëî äíåé ñ íà÷àëà ãîäà
CPU_INT16U const mon_add[13] = {0,0,31,59,90,120,151,181,212,243,273,304,334};
// ×èñëî äíåé â ìåñÿöàõ
CPU_INT08U const mon_len[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
void PrintRTCDateTimeStringRus(char *str, TRTC_Data *rtc)
{
sprintf(str, "%02d:%02d:%02d %02d/%02d/%02d", rtc->hour, rtc->min, rtc->sec, rtc->date, rtc->mon, rtc->year);
}
void ScanRTCDateTimeStringRus(char *str, TRTC_Data *rtc)
{
int hour, min, sec, date, mon, year;
sscanf(str, "%02d:%02d:%02d %02d/%02d/%02d", &hour, &min, &sec, &date, &mon, &year);
rtc->year = year;
rtc->mon = mon;
rtc->date = date;
rtc->hour = hour;
rtc->min = min;
rtc->sec = sec;
}
// ïðîâåðêà êîððåêòíîñòè äàòû/âðåìåíè
int RTCCheckTime(TRTC_Data *rtc)
{
if (rtc->hour > 23) return -1;
if (rtc->min > 59) return -2;
if (rtc->sec > 59) return -3;
if ((rtc->mon > 12) || (rtc->mon < 1)) return -5;
if (rtc->year > 99) return -6;
if ((rtc->year%4 == 0) && (rtc->mon == 2))
{ // âèñîñêîñíûé
if ((rtc->date == 0) || (rtc->date > 29)) return -4;
}
else
{
if ((rtc->date == 0) || (rtc->date > mon_len[rtc->mon])) return -4;
}
return 0;
}
void PrintRTCDateTimeString(char *str, TRTC_Data *rtc)
{
sprintf(str, "20%02d/%02d/%02d %02d:%02d:%02d", rtc->year, rtc->mon, rtc->date, rtc->hour, rtc->min, rtc->sec);
}
void PrintRTCTimeString(char *str, TRTC_Data *rtc)
{
sprintf(str, "%02d:%02d:%02d", rtc->hour, rtc->min, rtc->sec);
}
void PrintTimeString(char *str, CPU_INT32U time)
{
TRTC_Data rtc_data;
Sec2Date(&rtc_data, time);
PrintRTCDateTimeStringRus(str, &rtc_data);
}
void PrintSecToMinSec(char *str, int seconds)
{
int min_ = seconds/60;
int sec_ = seconds%60;
sprintf(str, "%02d:%02d", min_, sec_);
}
void PrintSecToHourMinSec(char *str, int seconds)
{
int min_ = (seconds/60)%60;
int sec_ = seconds%60;
int hour_ = seconds/3600;
sprintf(str, "%02d:%02d:%02d", hour_, min_, sec_);
}
void PrintSecToBigHourMinSec(char *str, int seconds)
{
int min_ = (seconds/60)%60;
int sec_ = seconds%60;
int hour_ = seconds/3600;
sprintf(str, "%d:%02d:%02d", hour_, min_, sec_);
}
CPU_INT32U Date2Sec(TRTC_Data *pData, CPU_INT08U ucType)
{ // Ðàñ÷åò ãîäà îò Ðîæäåñòâà Õðèñòîâà
CPU_INT16U year = (CPU_INT16U)pData->year + ((pData->year >= 70) ? 1900 : 2000);
//Ðàñ÷åò ìåñÿöåâ îò Ðîæäåñòâà Õðèñòîâà
CPU_INT32U ulIndex = (CPU_INT32U)(((year - 1) * 12) + pData->mon - 1);
//Äëÿ ìåñÿ÷íîãî àðõèâà ðàñ÷åò çàêîí÷åí.
if ( ucType != MONTH_TYPE )
{ //Ðàñ÷åò äíåé îò Ðîæåäñòâà Õðèñòîâà
ulIndex = ((year - 1) * 365L) + ((year - 1)/4) + mon_add[pData->mon] + pData->date;
//Êîððåêöèÿ íà òåêóùèé âèñîêîñíûé ãîä.
if ( (!(year % 4)) && (pData->mon > 2) ) {ulIndex++;}
//Äëÿ ñóòî÷íîãî àðõèâà ðàñ÷åò çàêîí÷åí
if ( ucType != DAY_TYPE )
{ //×èñëî ÷àcîâ
ulIndex = ulIndex * 24L + pData->hour;
if ( ucType != HOUR_TYPE )
{ //×èñëî ìèíóò.
ulIndex = ulIndex * 60L + pData->min;
if ( ucType != MIN_TYPE )
{ //×èñëî ñåêóíä.
ulIndex = ulIndex * 60L + pData->sec;
}//if( )
}//if( )
}//if( )
}//if( )
return ulIndex;
}
//------------------------------------------------------------------------
//Ðàñ÷åò ñåêóíä ñ 1 ÿíâàðÿ 1970 äî ìîìåíòà, îïðåäåëÿåìîãî ñòðóêòóðîé pData
//------------------------------------------------------------------------
CPU_INT32U GetSec( TRTC_Data *pData)
{
CPU_INT32U ulIndex = Date2Sec(pData, MIN_TYPE);//Ïîëó÷àåì ÷èñëî ìèíóò î Ðîæäåñòâà Õðèñòîâà.
ulIndex -= JESUS_TO_70MIN; //Ïîëó÷àåì ÷èñëî ìèíóò ñ 1 ÿíâàðÿ 1970 ãîäà.
ulIndex *= 60L; //Ïåðåâîäèì â ñåêóíäû
ulIndex += pData->sec; //Äîáàâëÿåì ÷èñëî ñåêóíä â äàííîé ìèíóòå.
return ulIndex;
}
// ïîëó÷åíèå ñèñòåìíîãî âðåìåíè â ñeêóíäàõ
CPU_INT32U GetTimeSec(void)
{
TRTC_Data rtc;
RTC_ReadTime(&rtc);
return GetSec(&rtc);
}
//Ïåðåâîä ÷èñëà ñåêóíä â ÷àñû
void Sec2Hour(TRTC_Data *pDest, CPU_INT32U ulSec)
{
pDest->year = 0;
pDest->mon = 0;
pDest->date = 0;
pDest->hour = ulSec/3600L; //÷àñû
ulSec %= 3600L;
pDest->min = ulSec/60L; //ìèíóòû
ulSec %= 60L;
pDest->sec = ulSec; //ñåêóíäû
}
// Ïåðåâîä ÷èñëà ñåêóíä ñ 1 ÿíâàðÿ 1970 ãîäà â ïàðàìåòðû ñòðóêòóðû TRTC_Data.
void Sec2Date(TRTC_Data *pDest, CPU_INT32U ulSec)
{
CPU_INT32U dl = 0;
dl = (ulSec)/86400L;
// óçíàëè äåíü íåäåëè
pDest->day = (dl+4)%7;
if ( ulSec >= 946684800L )
{ //Äàòà ïîçæå 1 ÿíâàðÿ 2000 ãîäà
ulSec -= 946684800L;
pDest->year = 0;
}//if( )
else
{ //Äàòà îò 1970 ãîäà äî 1999 ãîäà
pDest->year = 70;
}//else ( )
for ( dl = 365L;
ulSec >= (dl = 86400L * (365L + visocosn(pDest->year)));
ulSec -= dl, pDest->year++ ){;}
for ( pDest->mon = 1;
ulSec >= ( dl = 86400L *
(mon_len[pDest->mon] + ((pDest->mon == 2) ?
visocosn(pDest->year) : 0))); ulSec -= dl, pDest->mon++){;}
pDest->date = ulSec / (86400L) + 1;
ulSec %= 86400L;
pDest->hour = ulSec / 3600L;
ulSec %= 3600L;
pDest->min = ulSec / 60L;
ulSec %= 60L;
pDest->sec = ulSec;
}