Перенесена из k1921vk028/1921vk028/lib/rtc_service. Ядро rtc_service_core.c зависит только от stddef, string и собственных заголовков; доступ к часам и backup-памяти вынесен в rtc_service_port.h. Порт для K1921VK028 идёт в комплекте и служит образцом для следующего МК.
128 lines
4.2 KiB
C
128 lines
4.2 KiB
C
/**
|
||
****************************************************************************
|
||
* @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;
|
||
}
|