Начало

This commit is contained in:
cfif 2025-09-23 17:12:43 +03:00
commit c32bf18021
3 changed files with 269 additions and 0 deletions

29
Inc/RtcArtery.h Normal file
View File

@ -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

223
Src/RtcArtery.c Normal file
View File

@ -0,0 +1,223 @@
//
// Created by cfif on 17.11.22.
//
#include "RtcArtery.h"
#include <SystemDelayInterface.h>
#include <time.h>
#include <string.h>
#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;
}

17
modular.json Normal file
View File

@ -0,0 +1,17 @@
{
"dep": [
{
"type": "git",
"provider": "HVAC_DEV",
"repo": "Rtc"
}
],
"cmake": {
"inc_dirs": [
"Inc"
],
"srcs": [
"Src/**.c"
]
}
}