Files
arcs/arcs-sdk/drivers/lisa_rtc/lisa_rtc.h
2026-08-13 16:50:52 +08:00

316 lines
9.6 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* Copyright (c) 2025, LISTENAI
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file lisa_rtc.h
* @brief LISA RTC 实时时钟设备驱动接口
*/
#pragma once
#include "lisa_device.h"
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/* ========================================================================
* RTC 类型定义
* ======================================================================== */
/**
* @brief RTC 时间结构体
*/
typedef struct {
uint16_t year; /* 年份 (0-127,起始年份2000年,即0表示2000年,127表示2127年) */
uint8_t month; /* 月份 (1-12) */
uint8_t day; /* 日期 (1-31) */
uint8_t weekday; /* 星期 (0-6, 0=Sunday) */
uint8_t hour; /* 小时 (0-23) */
uint8_t minute; /* 分钟 (0-59) */
uint8_t second; /* 秒 (0-59) */
} lisa_rtc_time_t;
/**
* @brief RTC 闹钟结构体
*/
typedef struct {
uint16_t year; /* 年份 (0-127,起始年份2000年,即0表示2000年,127表示2127年) */
uint8_t month; /* 月份 (1-12) */
uint8_t day; /* 日期 (1-31) */
uint8_t weekday; /* 星期 (0-6, 0=Sunday) */
uint8_t hour; /* 小时 (0-23) */
uint8_t minute; /* 分钟 (0-59) */
uint8_t second; /* 秒 (0-59) */
} lisa_rtc_alarm_t;
/**
* @brief RTC 事件类型
*/
typedef enum {
LISA_RTC_EVENT_ALARM = (1 << 0), /* 闹钟事件 */
LISA_RTC_EVENT_SECOND = (1 << 1), /* 秒中断事件 */
LISA_RTC_EVENT_MINUTE = (1 << 2), /* 分钟中断事件 */
LISA_RTC_EVENT_HOUR = (1 << 3), /* 小时中断事件 */
} lisa_rtc_event_t;
/**
* @brief RTC 能力结构体
*/
typedef struct {
bool has_alarm; /* 是否支持闹钟 */
uint8_t alarm_count; /* 支持的闹钟数量 */
uint16_t min_year; /* 最小年份 */
uint16_t max_year; /* 最大年份 */
} lisa_rtc_capabilities_t;
/**
* @brief RTC 事件回调函数类型
*
* @param event 事件类型位掩码
* @param user_data 用户数据指针
*/
typedef void (*lisa_rtc_callback_t)(uint32_t event, void *user_data);
/* ========================================================================
* RTC 设备 API 结构体
* ======================================================================== */
typedef struct {
int (*set_time)(lisa_device_t *dev, const lisa_rtc_time_t *time);
int (*get_time)(lisa_device_t *dev, lisa_rtc_time_t *time);
int (*set_alarm)(lisa_device_t *dev, uint8_t alarm_id, const lisa_rtc_alarm_t *alarm);
int (*get_alarm)(lisa_device_t *dev, uint8_t alarm_id, lisa_rtc_alarm_t *alarm);
int (*enable_alarm)(lisa_device_t *dev, uint8_t alarm_id, bool enable);
int (*set_periodic_int)(lisa_device_t *dev, lisa_rtc_event_t event, bool enable);
int (*get_capabilities)(lisa_device_t *dev, lisa_rtc_capabilities_t *caps);
int (*set_callback)(lisa_device_t *dev, lisa_rtc_callback_t callback, void *user_data);
} lisa_rtc_api_t;
/* ========================================================================
* RTC 对外接口函数
* ======================================================================== */
/**
* @brief 设置RTC时间
*
* @param dev RTC设备指针
* @param time 时间结构体
*
* @return 0 成功
* @return LISA_DEVICE_ERR_INVALID 参数无效
* @return LISA_DEVICE_ERR_NOT_SUPPORT 不支持该操作
* @return <0 其他错误
*/
static inline int lisa_rtc_set_time(lisa_device_t *dev, const lisa_rtc_time_t *time)
{
if (!dev || !dev->api || !time) {
return LISA_DEVICE_ERR_INVALID;
}
/* 参数合法性检查 */
if (time->year > 127U || time->month < 1U || time->month > 12U ||
time->day < 1U || time->day > 31U || time->weekday > 6U ||
time->hour > 23U || time->minute > 59U || time->second > 59U) {
return LISA_DEVICE_ERR_INVALID;
}
lisa_rtc_api_t *api = (lisa_rtc_api_t *)dev->api;
return api->set_time ? api->set_time(dev, time) : LISA_DEVICE_ERR_NOT_SUPPORT;
}
/**
* @brief 获取RTC时间
*
* @param dev RTC设备指针
* @param time 输出参数,用于接收时间
*
* @return 0 成功
* @return LISA_DEVICE_ERR_INVALID 参数无效
* @return LISA_DEVICE_ERR_NOT_SUPPORT 不支持该操作
* @return <0 其他错误
*/
static inline int lisa_rtc_get_time(lisa_device_t *dev, lisa_rtc_time_t *time)
{
if (!dev || !dev->api || !time) {
return LISA_DEVICE_ERR_INVALID;
}
lisa_rtc_api_t *api = (lisa_rtc_api_t *)dev->api;
return api->get_time ? api->get_time(dev, time) : LISA_DEVICE_ERR_NOT_SUPPORT;
}
/**
* @brief 设置闹钟
*
* @param dev RTC设备指针
* @param alarm_id 闹钟ID (0-N)
* @param alarm 闹钟配置
*
* @return 0 成功
* @return LISA_DEVICE_ERR_INVALID 参数无效
* @return LISA_DEVICE_ERR_NOT_SUPPORT 不支持该操作
* @return <0 其他错误
*/
static inline int lisa_rtc_set_alarm(lisa_device_t *dev, uint8_t alarm_id, const lisa_rtc_alarm_t *alarm)
{
if (!dev || !dev->api || !alarm) {
return LISA_DEVICE_ERR_INVALID;
}
/* 参数合法性检查 */
if (alarm->year > 127U || alarm->month < 1U || alarm->month > 12U ||
alarm->day < 1U || alarm->day > 31U ||
alarm->hour > 23U || alarm->minute > 59U || alarm->second > 59U) {
return LISA_DEVICE_ERR_INVALID;
}
lisa_rtc_api_t *api = (lisa_rtc_api_t *)dev->api;
return api->set_alarm ? api->set_alarm(dev, alarm_id, alarm) : LISA_DEVICE_ERR_NOT_SUPPORT;
}
/**
* @brief 获取闹钟配置
*
* @param dev RTC设备指针
* @param alarm_id 闹钟ID (0-N)
* @param alarm 输出参数,用于接收闹钟配置
*
* @return 0 成功
* @return LISA_DEVICE_ERR_INVALID 参数无效
* @return LISA_DEVICE_ERR_NOT_SUPPORT 不支持该操作
* @return <0 其他错误
*/
static inline int lisa_rtc_get_alarm(lisa_device_t *dev, uint8_t alarm_id, lisa_rtc_alarm_t *alarm)
{
if (!dev || !dev->api || !alarm) {
return LISA_DEVICE_ERR_INVALID;
}
lisa_rtc_api_t *api = (lisa_rtc_api_t *)dev->api;
return api->get_alarm ? api->get_alarm(dev, alarm_id, alarm) : LISA_DEVICE_ERR_NOT_SUPPORT;
}
/**
* @brief 启用或禁用闹钟
*
* @param dev RTC设备指针
* @param alarm_id 闹钟ID (0-N)
* @param enable true=启用, false=禁用
*
* @return 0 成功
* @return LISA_DEVICE_ERR_INVALID 参数无效
* @return LISA_DEVICE_ERR_NOT_SUPPORT 不支持该操作
* @return <0 其他错误
*/
static inline int lisa_rtc_enable_alarm(lisa_device_t *dev, uint8_t alarm_id, bool enable)
{
if (!dev || !dev->api) {
return LISA_DEVICE_ERR_INVALID;
}
lisa_rtc_api_t *api = (lisa_rtc_api_t *)dev->api;
return api->enable_alarm ? api->enable_alarm(dev, alarm_id, enable) : LISA_DEVICE_ERR_NOT_SUPPORT;
}
/**
* @brief 设置周期性中断
*
* @param dev RTC设备指针
* @param event 中断类型 (SECOND/MINUTE/HOUR)
* @param enable true=启用, false=禁用
*
* @return 0 成功
* @return LISA_DEVICE_ERR_INVALID 参数无效
* @return LISA_DEVICE_ERR_NOT_SUPPORT 不支持该操作
* @return <0 其他错误
*
* @note 某些硬件只能同时启用一种周期性中断
*/
static inline int lisa_rtc_set_periodic_int(lisa_device_t *dev, lisa_rtc_event_t event, bool enable)
{
if (!dev || !dev->api) {
return LISA_DEVICE_ERR_INVALID;
}
/* 参数合法性检查event必须是有效的周期性中断类型 */
if (event != LISA_RTC_EVENT_SECOND &&
event != LISA_RTC_EVENT_MINUTE &&
event != LISA_RTC_EVENT_HOUR) {
return LISA_DEVICE_ERR_INVALID;
}
lisa_rtc_api_t *api = (lisa_rtc_api_t *)dev->api;
return api->set_periodic_int ? api->set_periodic_int(dev, event, enable) : LISA_DEVICE_ERR_NOT_SUPPORT;
}
/**
* @brief 获取RTC设备能力
*
* @param dev RTC设备指针
* @param caps 输出参数,用于接收设备能力信息
*
* @return 0 成功
* @return LISA_DEVICE_ERR_INVALID 参数无效
* @return LISA_DEVICE_ERR_NOT_SUPPORT 不支持该操作
* @return <0 其他错误
*/
static inline int lisa_rtc_get_capabilities(lisa_device_t *dev, lisa_rtc_capabilities_t *caps)
{
if (!dev || !dev->api || !caps) {
return LISA_DEVICE_ERR_INVALID;
}
lisa_rtc_api_t *api = (lisa_rtc_api_t *)dev->api;
return api->get_capabilities ? api->get_capabilities(dev, caps) : LISA_DEVICE_ERR_NOT_SUPPORT;
}
/**
* @brief 设置RTC事件回调函数
*
* @param dev RTC设备指针
* @param callback 回调函数指针
* @param user_data 用户数据指针
*
* @return 0 成功
* @return LISA_DEVICE_ERR_INVALID 参数无效
* @return LISA_DEVICE_ERR_NOT_SUPPORT 不支持该操作
* @return <0 其他错误
*/
static inline int lisa_rtc_set_callback(lisa_device_t *dev, lisa_rtc_callback_t callback, void *user_data)
{
if (!dev || !dev->api) {
return LISA_DEVICE_ERR_INVALID;
}
lisa_rtc_api_t *api = (lisa_rtc_api_t *)dev->api;
return api->set_callback ? api->set_callback(dev, callback, user_data) : LISA_DEVICE_ERR_NOT_SUPPORT;
}
/* ========================================================================
* 便捷宏定义
* ======================================================================== */
/**
* @brief 星期枚举
*/
#define LISA_RTC_WEEKDAY_SUNDAY 0
#define LISA_RTC_WEEKDAY_MONDAY 1
#define LISA_RTC_WEEKDAY_TUESDAY 2
#define LISA_RTC_WEEKDAY_WEDNESDAY 3
#define LISA_RTC_WEEKDAY_THURSDAY 4
#define LISA_RTC_WEEKDAY_FRIDAY 5
#define LISA_RTC_WEEKDAY_SATURDAY 6
/**
* @brief 闹钟忽略标志
*/
#define LISA_RTC_ALARM_IGNORE_YEAR 0
#define LISA_RTC_ALARM_IGNORE_MONTH 0
#define LISA_RTC_ALARM_IGNORE_DAY 0
#define LISA_RTC_ALARM_IGNORE_WEEKDAY 0xFF
#ifdef __cplusplus
}
#endif