From c32bf180217607495b52e4add4a4900d5dc91a00 Mon Sep 17 00:00:00 2001 From: cfif Date: Tue, 23 Sep 2025 17:12:43 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9D=D0=B0=D1=87=D0=B0=D0=BB=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Inc/RtcArtery.h | 29 +++++++ Src/RtcArtery.c | 223 ++++++++++++++++++++++++++++++++++++++++++++++++ modular.json | 17 ++++ 3 files changed, 269 insertions(+) create mode 100644 Inc/RtcArtery.h create mode 100644 Src/RtcArtery.c create mode 100644 modular.json diff --git a/Inc/RtcArtery.h b/Inc/RtcArtery.h new file mode 100644 index 0000000..d0c8369 --- /dev/null +++ b/Inc/RtcArtery.h @@ -0,0 +1,29 @@ +// +// Created by cfif on 17.11.22. +// + +#ifndef RTC_ARTERY_H +#define RTC_ARTERY_H + +#include "Rtc.h" +#include "cmsis_os2.h" + +typedef struct { + +#ifdef ACCESS_RTC + osMutexId_t access; +#endif + +} tRtcArtery; + +void RtcArtery_Init(tRtcArtery *env); + +tRtcIO RtcArtery_GetIo(tRtcArtery *env); + +///deprecated +tRtcArtery vRtcInit(); + +///deprecated +#define vRtcGetIo RtcArtery_GetIo + +#endif //RTC_ARTERY_H diff --git a/Src/RtcArtery.c b/Src/RtcArtery.c new file mode 100644 index 0000000..a2100c6 --- /dev/null +++ b/Src/RtcArtery.c @@ -0,0 +1,223 @@ +// +// Created by cfif on 17.11.22. +// +#include "RtcArtery.h" +#include +#include +#include +#include "at32f435_437.h" + +///deprecated +tRtcArtery vRtcInit() { + tRtcArtery rtcArtery; + RtcArtery_Init(&rtcArtery); + return rtcArtery; +} + +void RtcArtery_Init(tRtcArtery *env) { + + // enable the pwc clock + crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE); + + // allow access to ertc + pwc_battery_powered_domain_access(TRUE); + + // reset ertc bpr domain + crm_battery_powered_domain_reset(TRUE); + crm_battery_powered_domain_reset(FALSE); + + // enable the lext osc + crm_clock_source_enable(CRM_CLOCK_SOURCE_LEXT, TRUE); + + // wait till lext is ready + while (crm_flag_get(CRM_LEXT_STABLE_FLAG) == RESET) { + } + + // select the ertc clock source + crm_ertc_clock_select(CRM_ERTC_CLOCK_LEXT); + + // enable the ertc clock + crm_ertc_clock_enable(TRUE); + + // deinitializes the ertc registers + ertc_reset(); + + // wait for ertc apb registers update + ertc_wait_update(); + + // configure the ertc divider + // ertc second(1hz) = ertc_clk / (div_a + 1) * (div_b + 1 + ertc_divider_set(127, 255); + + // configure the ertc hour mode + ertc_hour_mode_set(ERTC_HOUR_MODE_24); + + // set date + ertc_date_set(123, 6, 3, 6); + // set time + ertc_time_set(0, 0, 1, ERTC_AM); + + +#ifdef ACCESS_RTC + + *env = (tRtcArtery) { + .access = osMutexNew(NULL) + }; + +#else + *env = (tRtcArtery) { + + }; +#endif + + +} + +static uint16_t vRtcSet(tRtcArtery *env, time_t *timestamp) { + struct tm dateTime; + +#ifdef ACCESS_RTC + if (osMutexAcquire(env->access, 1000) == osOK) { + localtime_r(timestamp, &dateTime); + + // set date + ertc_date_set(dateTime.tm_year, dateTime.tm_mon + 1, dateTime.tm_mday, dateTime.tm_wday); + // set time + ertc_time_set(dateTime.tm_hour, dateTime.tm_min, dateTime.tm_sec, ERTC_AM); + + osMutexRelease(env->access); + } else { + localtime_r(timestamp, &dateTime); + + // set date + ertc_date_set(dateTime.tm_year, dateTime.tm_mon + 1, dateTime.tm_mday, dateTime.tm_wday); + // set time + ertc_time_set(dateTime.tm_hour, dateTime.tm_min, dateTime.tm_sec, ERTC_AM); + } +#else + localtime_r(timestamp, &dateTime); + + // set date + ertc_date_set(dateTime.tm_year, dateTime.tm_mon + 1, dateTime.tm_mday, dateTime.tm_wday); + // set time + ertc_time_set(dateTime.tm_hour, dateTime.tm_min, dateTime.tm_sec, ERTC_AM); +#endif + + + return 0; +} + +static uint16_t vRtcSetTM(tRtcArtery *env, struct tm *timestampTM) { + +#ifdef ACCESS_RTC + if (osMutexAcquire(env->access, 1000) == osOK) { + // set date + ertc_date_set(timestampTM->tm_year, timestampTM->tm_mon + 1, timestampTM->tm_mday, timestampTM->tm_wday); + // set time + ertc_time_set(timestampTM->tm_hour, timestampTM->tm_min, timestampTM->tm_sec, ERTC_AM); + + osMutexRelease(env->access); + } else { + // set date + ertc_date_set(timestampTM->tm_year, timestampTM->tm_mon + 1, timestampTM->tm_mday, timestampTM->tm_wday); + // set time + ertc_time_set(timestampTM->tm_hour, timestampTM->tm_min, timestampTM->tm_sec, ERTC_AM); + } +#else + // set date + ertc_date_set(timestampTM->tm_year, timestampTM->tm_mon + 1, timestampTM->tm_mday, timestampTM->tm_wday); + // set time + ertc_time_set(timestampTM->tm_hour, timestampTM->tm_min, timestampTM->tm_sec, ERTC_AM); +#endif + + return 0; +} + +static void v_RtcGet(time_t *timestamp) { + ertc_time_type time; + + ertc_calendar_get(&time); + + struct tm dateTime; + + memset(&dateTime, 0, sizeof(dateTime)); + + dateTime.tm_year = time.year; + dateTime.tm_mon = time.month - 1; + dateTime.tm_mday = time.day; + dateTime.tm_hour = time.hour; + dateTime.tm_min = time.min; + dateTime.tm_sec = time.sec; + + *timestamp = mktime(&dateTime); + *timestamp &= 0xFFFFFFFF; + +} + +static uint16_t vRtcGet(tRtcArtery *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) { + ertc_time_type time; + + ertc_calendar_get(&time); + + memset(timestampTM, 0, sizeof(struct tm)); + + timestampTM->tm_year = time.year; + timestampTM->tm_mon = time.month - 1; + timestampTM->tm_mday = time.day; + timestampTM->tm_hour = time.hour; + timestampTM->tm_min = time.min; + timestampTM->tm_sec = time.sec; + +} + +static uint16_t vRtcGetTM(tRtcArtery *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 RtcArtery_GetIo(tRtcArtery *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..2325722 --- /dev/null +++ b/modular.json @@ -0,0 +1,17 @@ +{ + "dep": [ + { + "type": "git", + "provider": "HVAC_DEV", + "repo": "Rtc" + } + ], + "cmake": { + "inc_dirs": [ + "Inc" + ], + "srcs": [ + "Src/**.c" + ] + } +} \ No newline at end of file