mirror of
https://github.com/dimoniche/solarium.vlad.git
synced 2026-01-30 21:13:31 +03:00
370 lines
9.0 KiB
C
370 lines
9.0 KiB
C
#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 PrintRTCDateStringRus(char *str, TRTC_Data *rtc)
|
|
{
|
|
sprintf(str, "%02d/%02d/%02d", 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;
|
|
}
|
|
|
|
void ScanRTCDateStringRus(char *str, TRTC_Data *rtc)
|
|
{
|
|
int date, mon, year;
|
|
sscanf(str, "%02d/%02d/%02d", &date, &mon, &year);
|
|
rtc->year = year;
|
|
rtc->mon = mon;
|
|
rtc->date = date;
|
|
rtc->hour = 0;
|
|
rtc->min = 0;
|
|
rtc->sec = 0;
|
|
}
|
|
|
|
// ïðîâåðêà êîððåêòíîñòè äàòû/âðåìåíè
|
|
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 PrintSecDateTimeStringRaw(char *str, CPU_INT32U time)
|
|
{
|
|
TRTC_Data rtc_data;
|
|
Sec2Date(&rtc_data, time);
|
|
sprintf(str, "20%02d%02d%02d_%02d%02d%02d", rtc_data.year, rtc_data.mon, rtc_data.date, rtc_data.hour, rtc_data.min, rtc_data.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 PrintDateString(char *str, CPU_INT32U time)
|
|
{
|
|
TRTC_Data rtc_data;
|
|
Sec2Date(&rtc_data, time);
|
|
PrintRTCDateStringRus(str, &rtc_data);
|
|
}
|
|
|
|
void PrintSecToMinSec(char *str, int seconds)
|
|
{
|
|
int min_ = seconds/60;
|
|
int sec_ = seconds%60;
|
|
sprintf(str, "%02d:%02d", min_, sec_);
|
|
}
|
|
|
|
void PrintSecToMinRounded(char *str, int seconds)
|
|
{
|
|
int min_;
|
|
|
|
if (seconds == 0)
|
|
{
|
|
min_ = 0;
|
|
}
|
|
else
|
|
{
|
|
min_ = seconds/60;
|
|
if (seconds % 60) min_++;
|
|
}
|
|
sprintf(str, "%d", min_);
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
|