Files
plant_car/drivers/include/sdrv_rtc.h
2025-11-08 13:26:19 +08:00

329 lines
9.5 KiB
C

/**
* @file sdrv_rtc.h
* @brief SemiDrive RTC driver header file.
*
* @copyright Copyright (c) 2022 Semidrive Semiconductor.
* All rights reserved.
*/
#ifndef _SDRV_RTC_H_
#define _SDRV_RTC_H_
#include <stdint.h>
#include <types.h>
#include <sdrv_common.h>
#include <reg.h>
#include <regs_base.h>
#define SDRV_RTC_REG_PARITY_ERR_ENABLE() \
sdrv_rtc_reg_parity_err_int_enable(APB_RTC1_BASE); \
sdrv_rtc_reg_parity_err_int_enable(APB_RTC2_BASE);
#define SDRV_RTC_REG_PARITY_ERR_DISABLE() \
sdrv_rtc_reg_parity_err_int_disable(APB_RTC1_BASE); \
sdrv_rtc_reg_parity_err_int_disable(APB_RTC2_BASE);
typedef int (*rtc_cb_t)(uint32_t irq, void *arg);
/**
* @brief RTC time structure.
*
* The RTC time structure uses Gregorian time.
*/
struct rtc_time {
uint32_t tm_subsec;/* subseconds, unit millisecond, 0~999 */
uint32_t tm_sec; /* seconds, 0~61 */
uint32_t tm_min; /* minutes, 0~59 */
uint32_t tm_hour; /* hour, 0~23 */
uint32_t tm_mday; /* day, 1~31 */
uint32_t tm_mon; /* month, 0~11 */
uint32_t tm_year; /* years since 1900 */
uint32_t tm_wday; /* day since Sunday, 0~6 */
uint32_t tm_yday; /* days since Jan. 1, 0~365 */
uint32_t tm_isdst; /* daylight saving time flag */
};
typedef enum sdrv_rtc_violation_enum {
SDRV_RTC_VIO_NONE = 0, /* rtc no violation */
SDRV_RTC_VIO_OVERFLOW = 1, /* rtc violation disable */
SDRV_RTC_VIO_DISABLE = 2, /* rtc violation overflow */
SDRV_RTC_VIO_ALL = 3, /* rtc violation overflow & disable */
} sdrv_rtc_violation_e;
/**
* @brief RTC device structure.
*/
typedef struct sdrv_rtc {
paddr_t base;
uint32_t wakeup_intr; /**< wake up interrupt num */
uint32_t periodic_intr; /**< periodical interrupt num */
uint32_t violation_intr; /**< violation interrupt num */
rtc_cb_t cb; /**< interrupt callback */
sdrv_rtc_violation_e vio_mask; /**< mask flag in violation interrupt */
} sdrv_rtc_t;
struct rtc_wkalrm {
unsigned char enable;
unsigned char pending;
struct rtc_time tm;
};
/* Define RTC WakeUp Enable Type */
typedef enum sdrv_rtc_wakeup_enable_type {
SDRV_WKUP_ENABLE = 0, /* Only enable wakeup */
SDRV_WKUP_ENABLE_IRQ = 1, /* Enable wakeup and IRQ */
SDRV_WKUP_ENABLE_REQ = 2, /* Enable wakeup and pmu requst */
SDRV_WKUP_ENABLE_ALL = 3, /* Enable wakeup, IRQ and pmu requst */
} sdrv_rtc_wakeup_enable_type_e;
typedef enum sdrv_general_purpose {
SDRV_RTC_GP0, /* RTC general purpose register 0 */
SDRV_RTC_GP1, /* RTC general purpose register 1 */
SDRV_RTC_GP2, /* RTC general purpose register 2 */
SDRV_RTC_GP3, /* RTC general purpose register 3 */
} sdrv_general_purpose_e;
/**
* @brief RTC status error code.
*/
enum sdrv_rtc_error {
SDRV_RTC_STATUS_INVALID_RTC_TIME = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_RTC, 1), /* Invalid RTC Time */
SDRV_RTC_STATUS_LOCK = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_RTC, 2), /* RTC lock error */
};
/**
* @brief Enable RTC Register parity error interrupt status.
*
* @param base RTC Controller Base.
*/
static inline void sdrv_rtc_reg_parity_err_int_enable(uint32_t base)
{
RMWREG32(base + 0x68U, 0, 1, 1);
}
/**
* @brief Disable RTC Register parity error interrupt status.
*
* @param base RTC Controller Base.
*/
static inline void sdrv_rtc_reg_parity_err_int_disable(uint32_t base)
{
RMWREG32(base + 0x68U, 0, 1, 0);
}
/**
* @brief check is leap yaer
*
* @param [in] year
* @return true is leap year, false is not leap year.
*/
static inline bool is_leap_year(uint32_t year)
{
return (!(year % 4) && (year % 100)) || !(year % 400);
}
/**
* @brief Simple algorithm to convert RTC time to Epoch seconds.
*
* Epoch seconds starts from 1970-1-1, 00:00:01
*
* @param [in] tm rtc time.
* @return uint64_t Number of seconds since Epoch.
*/
uint64_t rtc_to_epoch(struct rtc_time *tm);
/**
* @brief Simple algorithm to convert epoch seconds to RTC time.
*
* Epoch seconds starts from 1970-1-1, 00:00:01
*
* @param [out] tm rtc time
* @param [in] epoch_sec uint64_t number of seconds since epoch.
* @return 0 success, otherwise failed.
*/
status_t epoch_to_rtc(struct rtc_time *tm, uint64_t epoch_sec);
/**
* @brief Simple algorithm to convert RTC time to Epoch milliseconds.
*
* Epoch seconds starts from 1970-1-1, 00:00:00.001
*
* @param [in] tm rtc time.
* @return uint64_t number of milliseconds since epoch.
*/
uint64_t rtc_to_epoch_ms(struct rtc_time *tm);
/**
* @brief Simple algorithm to convert epoch milliseconds to RTC time.
*
* Epoch milliseconds starts from 1970-1-1, 00:00:00.001
*
* @param [out] tm rtc time
* @param [in] epoch_millisec uint64_t number of milliseconds since epoch.
* @return 0 success, otherwise failed.
*/
status_t epoch_ms_to_rtc(struct rtc_time *tm, uint64_t epoch_millisec);
/**
* @brief sdrv rtc enable.
*
* @param [in] dev sdrv rtc controller
* @param [in] enable enable or disable
* @return 0 success, otherwise failed.
*/
status_t sdrv_rtc_enable(sdrv_rtc_t *dev, bool enable);
/**
* @brief sdrv enable rtc wake up.
*
* @param [in] dev sdrv rtc controller
* @param [in] type sdrv rtc wake up type
* @param [in] enable enable or disable
* @return 0 success, otherwise failed.
*/
status_t sdrv_rtc_wakeup_enable(sdrv_rtc_t *dev,
sdrv_rtc_wakeup_enable_type_e type, bool enable);
/**
* @brief sdrv get rtc wake up status.
*
* @param [in] dev sdrv rtc controller
* @return 1 wakeup, 0 not wakeup.
*/
bool sdrv_rtc_get_wakeup_status(sdrv_rtc_t *dev);
/**
* @brief sdrv clear rtc wake up status.
*
* @param [in] dev sdrv rtc controller
* @return 0 success, otherwise failed.
*/
status_t sdrv_rtc_clear_wakeup_status(sdrv_rtc_t *dev);
/**
* @brief sdrv get rtc violation status.
*
* @param [in] dev sdrv rtc controller
* @return 0 no violation, 1 overflow violation, 2 disable violation, 3 overflow & disable
*/
sdrv_rtc_violation_e sdrv_rtc_get_violation_status(sdrv_rtc_t *dev);
/**
* @brief sdrv rtc clear violation status.
*
* @param [in] dev sdrv rtc controller
* @param [in] vio sdrv rtc violation type
* @return 0 success, otherwise failed.
*/
status_t sdrv_rtc_clear_violation_status(sdrv_rtc_t *dev,
sdrv_rtc_violation_e vio);
/**
* @brief sdrv rtc violation enable.
*
* @param [in] dev sdrv rtc controller
* @param [in] vio_mask sdrv rtc violation type
* @param [in] en violation enable or disable
* @return 0 success, otherwise failed.
*/
status_t sdrv_rtc_violation_intr_enable(sdrv_rtc_t *dev,
sdrv_rtc_violation_e vio, bool en);
/**
* @brief rtc get time
*
* Get current rtc time.
*
* @param [in] dev sdrv rtc controller
* @param [in] tm rtc time
* @return 0 success, otherwise failed.
*/
status_t sdrv_rtc_get_time(sdrv_rtc_t *dev, struct rtc_time *tm);
/**
* @brief rtc set time
*
* Set current rtc time.
*
* @param [in] dev sdrv rtc controller
* @param [in] tm rtc time
* @return 0 success, otherwise failed.
*/
status_t sdrv_rtc_set_time(sdrv_rtc_t *dev, struct rtc_time *tm);
/**
* @brief rtc get alarm
*
* Get rtc alarm time, rtc will trigger interrupt when rtc time arrives at alarm time.
*
* @param [in] dev sdrv rtc controller
* @param [in] alrm rtc wakeup alarm infomation
* @return 0 success, otherwise failed.
*/
status_t sdrv_rtc_get_alarm(sdrv_rtc_t *dev, struct rtc_wkalrm *alrm);
/**
* @brief rtc set alarm
*
* Set rtc alarm time, rtc will trigger interrupt when rtc time arrives at alarm time.
*
* @param [in] dev sdrv rtc controller
* @param [in] alrm rtc wakeup alarm config
* @return 0 success, otherwise failed.
*/
status_t sdrv_rtc_set_alarm(sdrv_rtc_t *dev, struct rtc_wkalrm *alrm);
/**
* @brief Enable rtc alarm.
*
* @param [in] dev sdrv rtc controller
* @param [in] enable enable or disable
* @return 0 success, otherwise failed.
*/
status_t sdrv_rtc_enable_alarm(sdrv_rtc_t *dev, bool enable);
/**
* @brief Enable rtc interrupt.
* @param [in] source rtc wakeup/periodical/violation interrupt num.
* @param [in] arg pointer to interrupt arg(rtc device structure).
* @param [in] cb callback function.
*/
status_t sdrv_rtc_enable_it(uint32_t source, void *arg, rtc_cb_t cb);
/**
* @brief disable rtc interrput.
* @param source rtc wakeup/periodical/violation interrupt num.
* @return 0 success, otherwise failed.
*/
status_t sdrv_rtc_disable_it(uint32_t source);
/**
* @brief Read rtc general purpose register.
*
* Data in general purpose register will not be lost until RTC power down.
*
* @param [in] dev sdrv rtc controller
* @param [in] gp_num sdrv general purpose register num
* @return general purpose register value
*/
uint32_t sdrv_rtc_read_general_purpose_reg(sdrv_rtc_t *dev, sdrv_general_purpose_e gp_num);
/**
* @brief Write rtc general purpose register.
*
* @param [in] dev sdrv rtc controller
* @param [in] gp_num sdrv general purpose register num
* @param [in] value general purpose register value
* @return 0 success, otherwise failed.
*/
status_t sdrv_rtc_write_general_purpose_reg(sdrv_rtc_t *dev, sdrv_general_purpose_e gp_num, uint32_t value);
/**
* @brief rtc lock.
*
* Once set rtc lock, rtc enable can not be changed until next power on reset.
*
* @param [in] dev sdrv rtc controller
* @return 0 success, otherwise failed.
*/
status_t sdrv_rtc_lock(sdrv_rtc_t *dev);
#endif /*_SDRV_RTC_H_*/