commit 495bb1220f7089e1bbdd5bdafaf0d5cace90aa94 Author: cfif Date: Tue Sep 30 15:52:33 2025 +0300 Добавлены интерфейсы и драйверы diff --git a/Inc/RtcFC7240.h b/Inc/RtcFC7240.h new file mode 100644 index 0000000..d4a5c22 --- /dev/null +++ b/Inc/RtcFC7240.h @@ -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 diff --git a/Src/RtcFC7240.c b/Src/RtcFC7240.c new file mode 100644 index 0000000..f4837cb --- /dev/null +++ b/Src/RtcFC7240.c @@ -0,0 +1,375 @@ +// +// Created by cfif on 17.11.22. +// +#include "RtcFC7240.h" +#include +#include +#include +#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; +} \ No newline at end of file diff --git a/modular.json b/modular.json new file mode 100644 index 0000000..28df365 --- /dev/null +++ b/modular.json @@ -0,0 +1,17 @@ +{ + "dep": [ + { + "type": "git", + "provider": "HVAC_M7", + "repo": "Rtc" + } + ], + "cmake": { + "inc_dirs": [ + "Inc" + ], + "srcs": [ + "Src/**.c" + ] + } +} \ No newline at end of file