Добавлены интерфейсы и драйверы
This commit is contained in:
commit
495bb1220f
|
|
@ -0,0 +1,29 @@
|
|||
//
|
||||
// Created by cfif on 17.11.22.
|
||||
//
|
||||
|
||||
#ifndef RTC_FLAGCHIP_H
|
||||
#define RTC_FLAGCHIP_H
|
||||
|
||||
#include "Rtc.h"
|
||||
#include "cmsis_os2.h"
|
||||
|
||||
typedef struct {
|
||||
|
||||
#ifdef ACCESS_RTC
|
||||
osMutexId_t access;
|
||||
#endif
|
||||
|
||||
} tRtcFlagchip;
|
||||
|
||||
void RtcFlagchip_Init(tRtcFlagchip *env);
|
||||
|
||||
tRtcIO RtcFlagchip_GetIo(tRtcFlagchip *env);
|
||||
|
||||
///deprecated
|
||||
tRtcFlagchip vRtcInit();
|
||||
|
||||
///deprecated
|
||||
#define vRtcGetIo RtcFlagchip_GetIo
|
||||
|
||||
#endif //RTC_FLAGCHIP_H
|
||||
|
|
@ -0,0 +1,375 @@
|
|||
//
|
||||
// Created by cfif on 17.11.22.
|
||||
//
|
||||
#include "RtcFC7240.h"
|
||||
#include <SystemDelayInterface.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include "fc7xxx_driver_csc.h"
|
||||
#include "fc7xxx_driver_scg.h"
|
||||
#include "fc7xxx_driver_rtc.h"
|
||||
|
||||
#define SECONDS_DAY 86400UL
|
||||
#define SECONDS_HOUR 3600UL
|
||||
#define SECONDS_MINUTE 60UL
|
||||
#define MINUTES_HOUR 60UL
|
||||
#define HOURS_DAY 24UL
|
||||
#define DAYS_LEAP_YEAR 366UL
|
||||
#define DAYS_COM_YEAR 365UL
|
||||
#define START_YEAR 1970UL
|
||||
#define END_YEAR 2099UL
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t u16Year; /**< Year */
|
||||
uint8_t u8Month; /**< Month */
|
||||
uint8_t u8Day; /**< Day */
|
||||
uint8_t u8Hour; /**< Hour */
|
||||
uint8_t u8Minute; /**< Minute */
|
||||
uint8_t u8Second; /**< Second */
|
||||
} RTC_TimeDate;
|
||||
|
||||
/* Table of month length (in days) for the Common-year*/
|
||||
static const uint8_t ComYear[] = {0U, 31U, 28U, 31U, 30U, 31U, 30U, 31U, 31U, 30U, 31U, 30U, 31U};
|
||||
|
||||
/* Table of month length (in days) for the Leap-year*/
|
||||
static const uint8_t LeapYear[] = {0U, 31U, 29U, 31U, 30U, 31U, 30U, 31U, 31U, 30U, 31U, 30U, 31U};
|
||||
|
||||
|
||||
static bool RTC_IsLeapYear(uint16_t u16Year)
|
||||
{
|
||||
bool bYearLeap = false;
|
||||
|
||||
if ((u16Year % 4U) > 0U)
|
||||
{
|
||||
bYearLeap = false;
|
||||
}
|
||||
else if ((u16Year % 100U) > 0U)
|
||||
{
|
||||
bYearLeap = true;
|
||||
}
|
||||
else if ((u16Year % 400U) > 0U)
|
||||
{
|
||||
bYearLeap = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
bYearLeap = true;
|
||||
}
|
||||
|
||||
/* Return the exit code */
|
||||
return bYearLeap;
|
||||
}
|
||||
|
||||
static bool RTC_CheckTimeDate(const RTC_TimeDate * const pTimeDate)
|
||||
{
|
||||
bool bCheckReturn = true;
|
||||
const uint8_t * pMonth;
|
||||
pMonth = RTC_IsLeapYear(pTimeDate->u16Year) ? LeapYear : ComYear;
|
||||
|
||||
if (pTimeDate->u16Year < START_YEAR || pTimeDate->u16Year > END_YEAR
|
||||
|| pTimeDate->u8Month < 1U || pTimeDate->u8Month > 12U
|
||||
|| pTimeDate->u8Day < 1U || pTimeDate->u8Day > pMonth[pTimeDate->u8Month]
|
||||
|| pTimeDate->u8Hour >= 24
|
||||
|| pTimeDate->u8Minute >= 60
|
||||
|| pTimeDate->u8Second >= 60)
|
||||
{
|
||||
bCheckReturn = false;
|
||||
}
|
||||
return bCheckReturn;
|
||||
}
|
||||
|
||||
static void RTC_TimeDate_To_Second(RTC_TimeDate * const pTimeDate, uint32_t u32Second)
|
||||
{
|
||||
uint32_t u32CountDays;
|
||||
uint32_t u32TempCount;
|
||||
uint32_t u32TempDays;
|
||||
|
||||
u32CountDays = u32Second / SECONDS_DAY;
|
||||
u32TempCount = u32Second % SECONDS_DAY;
|
||||
|
||||
pTimeDate->u8Hour = (uint8_t)(u32TempCount / SECONDS_HOUR);
|
||||
u32TempCount = u32TempCount % SECONDS_HOUR;
|
||||
|
||||
pTimeDate->u8Minute = (uint8_t)(u32TempCount / SECONDS_MINUTE);
|
||||
pTimeDate->u8Second = (uint8_t)(u32TempCount % SECONDS_MINUTE);
|
||||
|
||||
pTimeDate->u16Year = (uint16_t)START_YEAR;
|
||||
|
||||
u32TempDays = DAYS_COM_YEAR;
|
||||
while (u32CountDays >= u32TempDays)
|
||||
{
|
||||
pTimeDate->u16Year++;
|
||||
u32CountDays -= u32TempDays;
|
||||
u32TempDays = (RTC_IsLeapYear(pTimeDate->u16Year)) ? DAYS_LEAP_YEAR : DAYS_COM_YEAR;
|
||||
}
|
||||
|
||||
u32TempDays += 1;
|
||||
|
||||
for (uint8_t u8TempMonth = 1; u8TempMonth <= 12; u8TempMonth++)
|
||||
{
|
||||
u32TempCount = (RTC_IsLeapYear(pTimeDate->u16Year)) ? (uint32_t)LeapYear[u8TempMonth] : (uint32_t)ComYear[u8TempMonth];
|
||||
if (u32TempDays <= u32TempCount)
|
||||
{
|
||||
pTimeDate->u8Month = (uint8_t)u8TempMonth;
|
||||
pTimeDate->u8Day = (uint8_t)u32TempDays;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
u32TempDays -= u32TempCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t RTC_Second_To_TimeDate(const RTC_TimeDate * const pTimeDate)
|
||||
{
|
||||
uint32_t u32Second;
|
||||
|
||||
uint32_t u32TempDay;
|
||||
|
||||
u32Second = (pTimeDate->u16Year - START_YEAR) * SECONDS_DAY * DAYS_COM_YEAR;
|
||||
|
||||
for (uint32_t u32TempYear = START_YEAR; u32TempYear < pTimeDate->u16Year; u32TempYear++)
|
||||
{
|
||||
if (RTC_IsLeapYear((uint16_t)u32TempYear))
|
||||
{
|
||||
u32Second += SECONDS_DAY;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t u8TempMonth = 1; u8TempMonth < pTimeDate->u8Month; u8TempMonth++)
|
||||
{
|
||||
u32TempDay = (RTC_IsLeapYear(pTimeDate->u16Year)) ? (uint32_t)LeapYear[u8TempMonth] : (uint32_t)ComYear[u8TempMonth];
|
||||
u32Second += (u32TempDay * SECONDS_DAY);
|
||||
}
|
||||
|
||||
u32Second += ((uint32_t)((pTimeDate->u8Day - 1U) * SECONDS_DAY) + \
|
||||
pTimeDate->u8Hour * SECONDS_HOUR + \
|
||||
pTimeDate->u8Minute * SECONDS_MINUTE + \
|
||||
pTimeDate->u8Second);
|
||||
|
||||
return u32Second;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set time and date
|
||||
*
|
||||
* @param pRtcHandle the RTC instance
|
||||
* @param pTimeDate the structure of time and date
|
||||
*/
|
||||
static void RTC_SetTimeDate(const RTC_TimeDate *const pTimeDate) {
|
||||
uint32_t u32Second;
|
||||
|
||||
if (true == RTC_CheckTimeDate(pTimeDate)) {
|
||||
u32Second = RTC_Second_To_TimeDate(pTimeDate);
|
||||
RTC_SetSecondCounterValue(u32Second);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get time and date
|
||||
*
|
||||
* @param pRtcHandle the RTC instance
|
||||
* @param pTimeDate the structure of time and date
|
||||
*/
|
||||
void RTC_GetTimeDate(RTC_TimeDate * const pTimeDate)
|
||||
{
|
||||
uint32_t u32Second;
|
||||
|
||||
u32Second = RTC_GetTime();
|
||||
RTC_TimeDate_To_Second(pTimeDate, u32Second);
|
||||
}
|
||||
|
||||
tRtcFlagchip vRtcInit() {
|
||||
tRtcFlagchip rtcFlagchip;
|
||||
RtcFlagchip_Init(&rtcFlagchip);
|
||||
return rtcFlagchip;
|
||||
}
|
||||
|
||||
void RtcFlagchip_Init(tRtcFlagchip *env) {
|
||||
|
||||
// enable SIRC32K clock source
|
||||
SCG_Sirc32kType tSIRC32KStruct =
|
||||
{
|
||||
.bLock = true
|
||||
};
|
||||
SCG_EnableSIRC32K(&tSIRC32KStruct);
|
||||
// set RTC clock source is SIRC32K clock
|
||||
CSC0_AONCLKSRType tAONCLKStruct;
|
||||
tAONCLKStruct.eRtcSel = CSC0_RTC_SIRC32K_CLK;
|
||||
tAONCLKStruct.eAon32KSel = CSC0_AON32K_SIRCDIV_32K_CLK;
|
||||
tAONCLKStruct.eAonSel = CSC0_AON_SIRCDIV_128K_CLK;
|
||||
CSC0_SetAonClkSrc(&tAONCLKStruct, true);
|
||||
|
||||
|
||||
RTC_InitType tInitStruct = {0};
|
||||
tInitStruct.eSecIntAndClkoutFreq = RTC_FREQ_1HZ; // set interrupt frequency to 1HZ
|
||||
RTC_Init(&tInitStruct);
|
||||
|
||||
RTC_Start();
|
||||
|
||||
#ifdef ACCESS_RTC
|
||||
|
||||
*env = (tRtcFlagchip) {
|
||||
.access = osMutexNew(NULL)
|
||||
};
|
||||
|
||||
#else
|
||||
*env = (tRtcFlagchip) {
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
static uint16_t vRtcSet(tRtcFlagchip *env, time_t *timestamp) {
|
||||
struct tm dateTime;
|
||||
|
||||
RTC_TimeDate tTimeDate;
|
||||
|
||||
localtime_r(timestamp, &dateTime);
|
||||
|
||||
tTimeDate.u16Year = dateTime.tm_year + 1900;
|
||||
tTimeDate.u8Month = dateTime.tm_mon + 1;
|
||||
tTimeDate.u8Day = dateTime.tm_mday;
|
||||
tTimeDate.u8Hour = dateTime.tm_hour;
|
||||
tTimeDate.u8Minute = dateTime.tm_min;
|
||||
tTimeDate.u8Second = dateTime.tm_sec;
|
||||
|
||||
#ifdef ACCESS_RTC
|
||||
if (osMutexAcquire(env->access, 1000) == osOK) {
|
||||
|
||||
RTC_SetTimeDate(&tTimeDate);
|
||||
|
||||
osMutexRelease(env->access);
|
||||
} else {
|
||||
RTC_SetTimeDate(&tTimeDate);
|
||||
}
|
||||
#else
|
||||
RTC_SetTimeDate(&tTimeDate);
|
||||
#endif
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint16_t vRtcSetTM(tRtcFlagchip *env, struct tm *timestampTM) {
|
||||
|
||||
RTC_TimeDate tTimeDate;
|
||||
|
||||
tTimeDate.u16Year = timestampTM->tm_year + 1900;
|
||||
tTimeDate.u8Month = timestampTM->tm_mon + 1;
|
||||
tTimeDate.u8Day = timestampTM->tm_mday;
|
||||
tTimeDate.u8Hour = timestampTM->tm_hour;
|
||||
tTimeDate.u8Minute = timestampTM->tm_min;
|
||||
tTimeDate.u8Second = timestampTM->tm_sec;
|
||||
|
||||
#ifdef ACCESS_RTC
|
||||
if (osMutexAcquire(env->access, 1000) == osOK) {
|
||||
|
||||
RTC_SetTimeDate(&tTimeDate);
|
||||
|
||||
osMutexRelease(env->access);
|
||||
} else {
|
||||
RTC_SetTimeDate(&tTimeDate);
|
||||
}
|
||||
#else
|
||||
RTC_SetTimeDate(&tTimeDate);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void v_RtcGet(time_t *timestamp) {
|
||||
|
||||
RTC_TimeDate tTimeDate;
|
||||
|
||||
RTC_GetTimeDate(&tTimeDate);
|
||||
|
||||
struct tm dateTime;
|
||||
|
||||
memset(&dateTime, 0, sizeof(dateTime));
|
||||
|
||||
dateTime.tm_year = tTimeDate.u16Year - 1900;
|
||||
dateTime.tm_mon = tTimeDate.u8Month - 1;
|
||||
dateTime.tm_mday = tTimeDate.u8Day;
|
||||
dateTime.tm_hour = tTimeDate.u8Hour;
|
||||
dateTime.tm_min = tTimeDate.u8Minute;
|
||||
dateTime.tm_sec = tTimeDate.u8Second;
|
||||
|
||||
*timestamp = mktime(&dateTime);
|
||||
*timestamp &= 0xFFFFFFFF;
|
||||
|
||||
}
|
||||
|
||||
static uint16_t vRtcGet(tRtcFlagchip *env, time_t *timestamp) {
|
||||
|
||||
|
||||
#ifdef ACCESS_RTC
|
||||
if (osMutexAcquire(env->access, 1000) == osOK) {
|
||||
memset(timestamp, 0, sizeof(time_t));
|
||||
v_RtcGet(timestamp);
|
||||
osMutexRelease(env->access);
|
||||
} else {
|
||||
v_RtcGet(timestamp);
|
||||
}
|
||||
#else
|
||||
|
||||
v_RtcGet(timestamp);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void v_RtcGetTM(struct tm *timestampTM) {
|
||||
|
||||
RTC_TimeDate tTimeDate;
|
||||
|
||||
RTC_GetTimeDate(&tTimeDate);
|
||||
|
||||
|
||||
memset(timestampTM, 0, sizeof(struct tm));
|
||||
|
||||
timestampTM->tm_year = tTimeDate.u16Year - 1900;
|
||||
timestampTM->tm_mon = tTimeDate.u8Month - 1;
|
||||
timestampTM->tm_mday = tTimeDate.u8Day;
|
||||
timestampTM->tm_hour = tTimeDate.u8Hour;
|
||||
timestampTM->tm_min = tTimeDate.u8Minute;
|
||||
timestampTM->tm_sec = tTimeDate.u8Second;
|
||||
|
||||
}
|
||||
|
||||
static uint16_t vRtcGetTM(tRtcFlagchip *env, struct tm *timestampTM) {
|
||||
|
||||
#ifdef ACCESS_RTC
|
||||
if (osMutexAcquire(env->access, 1000) == osOK) {
|
||||
|
||||
v_RtcGetTM(timestampTM);
|
||||
|
||||
osMutexRelease(env->access);
|
||||
} else {
|
||||
v_RtcGetTM(timestampTM);
|
||||
}
|
||||
#else
|
||||
|
||||
v_RtcGetTM(timestampTM);
|
||||
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
tRtcIO RtcFlagchip_GetIo(tRtcFlagchip *env) {
|
||||
tRtcIO io = {
|
||||
.env = env,
|
||||
.get = (RtcIOTransaction) vRtcGet,
|
||||
.set = (RtcIOTransaction) vRtcSet,
|
||||
.getTM = (RtcIOTransactionTM) vRtcGetTM,
|
||||
.setTM = (RtcIOTransactionTM) vRtcSetTM
|
||||
};
|
||||
return io;
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"dep": [
|
||||
{
|
||||
"type": "git",
|
||||
"provider": "HVAC_M7",
|
||||
"repo": "Rtc"
|
||||
}
|
||||
],
|
||||
"cmake": {
|
||||
"inc_dirs": [
|
||||
"Inc"
|
||||
],
|
||||
"srcs": [
|
||||
"Src/**.c"
|
||||
]
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue