223 lines
5.2 KiB
C
223 lines
5.2 KiB
C
//
|
|
// 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;
|
|
} |