feat(rtc-service): служба RTC с резервированным backup-томом
Перенесена из k1921vk028/1921vk028/lib/rtc_service. Ядро rtc_service_core.c зависит только от stddef, string и собственных заголовков; доступ к часам и backup-памяти вынесен в rtc_service_port.h. Порт для K1921VK028 идёт в комплекте и служит образцом для следующего МК.
This commit is contained in:
127
c/rtc-service/rtc_service_port_k1921vk028.c
Normal file
127
c/rtc-service/rtc_service_port_k1921vk028.c
Normal file
@@ -0,0 +1,127 @@
|
||||
/**
|
||||
****************************************************************************
|
||||
* @file rtc_service_port_k1921vk028.c
|
||||
* @brief Порт RTC Service для семейства K1921VK028 (plib028).
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
#include "rtc_service_port.h"
|
||||
#include "rtc_service_types.h"
|
||||
|
||||
#include "plib028_bflash.h"
|
||||
#include "plib028_rtc.h"
|
||||
#include "plib028_rcu.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* Вывод: в данном HAL API явного выбора источника LSE/LSI на уровне C API нет,
|
||||
поэтому конфигурирование делается как AUTO с флагом активного источника AUTO. */
|
||||
|
||||
RtcService_PortResult RtcService_Port_InitClock(RtcService_ClockSource preferred_source,
|
||||
RtcService_ClockSource* actual_source)
|
||||
{
|
||||
if (actual_source != NULL) {
|
||||
*actual_source = RTC_SERVICE_CLOCK_SOURCE_AUTO;
|
||||
}
|
||||
|
||||
if (preferred_source != RTC_SERVICE_CLOCK_SOURCE_AUTO) {
|
||||
/* На текущей ревизии драйвер NIIЭТ не предоставляет стабильных API для ручного
|
||||
* выбора LSE/LSI через публичные функции. Рекомендуется использовать AUTO. */
|
||||
return RTC_SERVICE_PORT_RESULT_UNSUPPORTED_CLOCK;
|
||||
}
|
||||
|
||||
/* Включение тактирования RTC в RCC */
|
||||
RCU_APBClk0Cmd(RCU_APBClk0_RTC, ENABLE);
|
||||
|
||||
return RTC_SERVICE_PORT_OK;
|
||||
}
|
||||
|
||||
void RtcService_Port_EnableRtcClock(void)
|
||||
{
|
||||
/* На K1921VK028 дополнительной явной подготовки источника после включения тактирования
|
||||
* RTC/APB-блока, как правило, не требуется. Реализация оставлена явной для port API. */
|
||||
(void)0;
|
||||
}
|
||||
|
||||
uint8_t RtcService_Port_IsPowerOnReset(void)
|
||||
{
|
||||
/* TODO: при наличии отдельного API/регистра статуса сброса заменить на реальную проверку.
|
||||
* Безопасная дефолтная стратегия — считать, что это не cold reset. */
|
||||
return 0U;
|
||||
}
|
||||
|
||||
RtcService_PortResult RtcService_Port_ReadRtc(RtcService_DateTime* dt)
|
||||
{
|
||||
if (dt == NULL)
|
||||
return RTC_SERVICE_PORT_RESULT_HW_ERROR;
|
||||
|
||||
RTC_Time_TypeDef t = {0};
|
||||
RTC_Date_TypeDef d = {0};
|
||||
|
||||
RTC_GetTime(RTC_Format_BIN, &t);
|
||||
RTC_GetDate(RTC_Format_BIN, &d);
|
||||
|
||||
dt->year = (uint16_t)d.Year;
|
||||
dt->month = (uint16_t)d.Month;
|
||||
dt->day = (uint16_t)d.Day;
|
||||
dt->weekday = (uint16_t)d.Weekday;
|
||||
dt->hour = (uint16_t)t.Hour;
|
||||
dt->minute = (uint16_t)t.Minute;
|
||||
dt->second = (uint16_t)t.Second;
|
||||
|
||||
return RTC_SERVICE_PORT_OK;
|
||||
}
|
||||
|
||||
RtcService_PortResult RtcService_Port_WriteRtc(const RtcService_DateTime* dt)
|
||||
{
|
||||
RTC_Time_TypeDef t = {0};
|
||||
RTC_Date_TypeDef d = {0};
|
||||
|
||||
if (dt == NULL)
|
||||
return RTC_SERVICE_PORT_RESULT_HW_ERROR;
|
||||
|
||||
t.PSecond = 0U;
|
||||
t.Hour = dt->hour;
|
||||
t.Minute = dt->minute;
|
||||
t.Second = dt->second;
|
||||
d.Year = dt->year;
|
||||
d.Month = dt->month;
|
||||
d.Day = dt->day;
|
||||
d.Weekday = (RTC_Weekday_TypeDef)dt->weekday;
|
||||
|
||||
RTC_SetTime(RTC_Format_BIN, &t);
|
||||
RTC_SetDate(RTC_Format_BIN, &d);
|
||||
RTC_ShadowCmd(DISABLE);
|
||||
RTC_ShadowCmd(ENABLE);
|
||||
|
||||
return RTC_SERVICE_PORT_OK;
|
||||
}
|
||||
|
||||
RtcService_PortResult RtcService_Port_ReadBackup(uint32_t* buffer, size_t words)
|
||||
{
|
||||
if ((buffer == NULL) || (words == 0U))
|
||||
return RTC_SERVICE_PORT_RESULT_HW_ERROR;
|
||||
|
||||
for (size_t i = 0U; i < words; ++i) {
|
||||
BFLASH_ReadData((uint32_t)i, &buffer[i], BFLASH_Region_NVR);
|
||||
}
|
||||
return RTC_SERVICE_PORT_OK;
|
||||
}
|
||||
|
||||
RtcService_PortResult RtcService_Port_WriteBackup(const uint32_t* buffer, size_t words)
|
||||
{
|
||||
if ((buffer == NULL) || (words == 0U))
|
||||
return RTC_SERVICE_PORT_RESULT_HW_ERROR;
|
||||
|
||||
for (size_t i = 0U; i < words; ++i) {
|
||||
BFLASH_WriteData((uint32_t)i, (uint32_t*)&buffer[i], BFLASH_Region_NVR);
|
||||
}
|
||||
return RTC_SERVICE_PORT_OK;
|
||||
}
|
||||
|
||||
RtcService_PortResult RtcService_Port_EraseBackup(void)
|
||||
{
|
||||
BFLASH_ErasePage(0UL, BFLASH_Region_NVR);
|
||||
return RTC_SERVICE_PORT_OK;
|
||||
}
|
||||
Reference in New Issue
Block a user