922 lines
23 KiB
C
922 lines
23 KiB
C
#include "system/includes.h"
|
||
#include "rtc/alarm.h"
|
||
#include "common/app_common.h"
|
||
#include "system/timer.h"
|
||
#include "app_main.h"
|
||
#include "tone_player.h"
|
||
#include "app_task.h"
|
||
|
||
#if TCFG_APP_RTC_EN
|
||
#ifdef RTC_ALM_EN
|
||
/* #define ALARM_DEBUG_EN */
|
||
#ifdef ALARM_DEBUG_EN
|
||
#define alarm_printf printf
|
||
#define alarm_putchar putchar
|
||
#define alarm_printf_buf put_buf
|
||
#else
|
||
#define alarm_printf(...)
|
||
#define alarm_putchar(...)
|
||
#define alarm_printf_buf(...)
|
||
#endif
|
||
|
||
#define PRINT_FUN() alarm_printf("func : %s\n", __FUNCTION__)
|
||
#define PRINT_FUN_RETURN_INFO() alarm_printf("func : %s, line : %d.\n", __FUNCTION__, __LINE__)
|
||
|
||
/*************************************************************
|
||
此文件函数主要是rtc闹钟的实现代码
|
||
用户可以不主要关心实现,专心留意api调用
|
||
常用的api 有:
|
||
|
||
u8 alarm_add(PT_ALARM p, u8 index);
|
||
增加闹钟
|
||
|
||
void alarm_delete(u8 index);
|
||
删除闹钟
|
||
|
||
void rtc_update_time_api(struct sys_time *time)
|
||
更新时间api(更新了时间必须调用该接口)
|
||
|
||
u8 alarm_active_flag_get(void);
|
||
闹钟到达的标志
|
||
|
||
u8 alarm_get_info(PT_ALARM p, u8 index)
|
||
获取闹钟信息
|
||
|
||
u8 alarm_get_active_index(void);
|
||
获取当前激活使能的闹钟(可以理解为下一个会响的闹钟)
|
||
|
||
|
||
u8 alarm_get_total(void)
|
||
获取当前已经设备的闹钟数(包括关闭的闹钟)
|
||
|
||
|
||
void rtc_calculate_next_few_day(struct sys_time *data_time,u8 days)
|
||
获取今天星期几
|
||
|
||
|
||
void alarm_name_set(u8 *p, u8 index, u8 len)
|
||
设置闹钟名字
|
||
|
||
|
||
u8 alarm_name_get(u8 *p, u8 index)
|
||
获取闹钟名字
|
||
**************************************************************/
|
||
|
||
|
||
|
||
static volatile u8 g_alarm_active_flag = 0;
|
||
static volatile u8 alarm_cur_active = 0;//当前在响的闹钟
|
||
|
||
|
||
|
||
typedef struct __alarm_map__ {
|
||
u32 mask: 16;
|
||
u32 map :
|
||
((M_MAX_ALARM_NUMS + 7) / 8 * 8); //存储了闹钟数目信息(闹钟数)
|
||
u32 map_sw :
|
||
((M_MAX_ALARM_NUMS + 7) / 8 * 8); //存储闹钟的使能开关(闹钟开关)
|
||
u32 active_map :
|
||
((M_MAX_ALARM_NUMS + 7) / 8 * 8); //存储最后激活闹钟
|
||
} T_ALARM_MAP, *PT_ALARM_MAP;
|
||
|
||
|
||
/* volatile u8 g_alarm_ring_max_cnt = 100; */
|
||
|
||
static T_ALARM alarm_tab[M_MAX_ALARM_NUMS] = {0};
|
||
static u8 alarm_name[M_MAX_ALARM_NAME_LEN] = {0};
|
||
|
||
#define RTC_MASK (0x55aa+M_MAX_ALARM_NAME_LEN)
|
||
|
||
static void *dev_handle;
|
||
|
||
T_ALARM_MAP alarm_map = {0};
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* debug 函数代码 */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
|
||
void alarm_vm_puts_info(PT_ALARM p)
|
||
{
|
||
alarm_printf("index : %d\n", p->index);
|
||
alarm_printf("mode: %d\n", p->mode);
|
||
alarm_printf("sw: %d\n", p->sw);
|
||
/* alarm_puts_time(&(p->time)); */
|
||
}
|
||
|
||
void alarm_puts_time(struct sys_time *pTime)
|
||
{
|
||
u8 week = 0;
|
||
|
||
#if 1
|
||
alarm_printf("alarm_time : %d-%d-%d,%d:%d:%d\n", pTime->year, pTime->month, pTime->day, pTime->hour, pTime->min, pTime->sec);
|
||
week = rtc_calculate_week_val(pTime);
|
||
#endif
|
||
alarm_printf("alarm week : %d\n", week);
|
||
}
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* rtc 硬化相关代码*/
|
||
/*----------------------------------------------------------------------------*/
|
||
void *is_sys_time_online()
|
||
{
|
||
return dev_handle;
|
||
}
|
||
|
||
|
||
static void get_sys_time(struct sys_time *time)//获取时间
|
||
{
|
||
if (!dev_handle) {
|
||
return ;
|
||
}
|
||
dev_ioctl(dev_handle, IOCTL_GET_SYS_TIME, (u32)time);
|
||
}
|
||
|
||
static void set_sys_time(struct sys_time *time)//设置时间
|
||
{
|
||
if (!dev_handle) {
|
||
return ;
|
||
}
|
||
dev_ioctl(dev_handle, IOCTL_SET_SYS_TIME, (u32)time);
|
||
}
|
||
|
||
void alarm_hw_set_sw(u8 sw)//闹钟开关
|
||
{
|
||
/* printf("alarm sw : %d\n", sw); */
|
||
if (!dev_handle) {
|
||
return ;
|
||
}
|
||
dev_ioctl(dev_handle, IOCTL_SET_ALARM_ENABLE, !!sw);
|
||
}
|
||
|
||
void alarm_hw_write_time(struct sys_time *time, u8 sw)//写闹钟寄存器
|
||
{
|
||
if (!dev_handle) {
|
||
return ;
|
||
}
|
||
alarm_printf("alarm_time : %d-%d-%d,%d:%d:%d\n", time->year, time->month, time->day, time->hour, time->min, time->sec);
|
||
|
||
alarm_hw_set_sw(0);
|
||
dev_ioctl(dev_handle, IOCTL_SET_ALARM, (u32)time);
|
||
alarm_hw_set_sw(sw);
|
||
}
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* vm读写操作部分代码 */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
static void alarm_vm_reset()
|
||
{
|
||
int i = 0;
|
||
int ret = 0;
|
||
T_ALARM_MAP map_temp = {0};
|
||
memset(&map_temp, 0x0, sizeof(T_ALARM_MAP));
|
||
map_temp.mask = RTC_MASK;
|
||
ret = syscfg_write(VM_ALARM_MASK, (u8 *)&map_temp, sizeof(T_ALARM_MAP));
|
||
if (ret != sizeof(T_ALARM_MAP)) {
|
||
PRINT_FUN_RETURN_INFO();
|
||
return;
|
||
}
|
||
|
||
for (i = 0; i < M_MAX_ALARM_NUMS; i++) {
|
||
T_ALARM_VM tmp = {0};
|
||
tmp.head = RTC_MASK;
|
||
tmp.alarm.index = i;
|
||
ret = syscfg_write(VM_ALARM_0 + i, &tmp, sizeof(T_ALARM_VM));
|
||
if (ret != sizeof(T_ALARM_VM)) {
|
||
alarm_printf("The %d alarm write vm err!\n", index);
|
||
return;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
//写闹钟map表
|
||
static void alarm_vm_write_mask(PT_ALARM_MAP map)
|
||
{
|
||
int ret = 0;
|
||
PRINT_FUN();
|
||
T_ALARM_MAP map_temp = {0};
|
||
memcpy(&map_temp, map, sizeof(T_ALARM_MAP));
|
||
if (map_temp.mask != RTC_MASK) {
|
||
memset(&map_temp, 0x0, sizeof(T_ALARM_MAP));
|
||
map_temp.mask = RTC_MASK;
|
||
}
|
||
|
||
ret = syscfg_write(VM_ALARM_MASK, (u8 *)&map_temp, sizeof(T_ALARM_MAP));
|
||
if (ret != sizeof(T_ALARM_MAP)) {
|
||
PRINT_FUN_RETURN_INFO();
|
||
return;
|
||
}
|
||
}
|
||
|
||
//获取闹钟所有信息
|
||
static void alarm_vm_read_info(PT_ALARM_MAP map)
|
||
{
|
||
PRINT_FUN();
|
||
T_ALARM_VM tmp;
|
||
int ret = 0;
|
||
u8 i;
|
||
|
||
ret = syscfg_read(VM_ALARM_MASK, (u8 *)map, sizeof(T_ALARM_MAP));
|
||
if (ret != sizeof(T_ALARM_MAP) || map->mask != RTC_MASK) {
|
||
PRINT_FUN_RETURN_INFO();
|
||
memset(map, 0, sizeof(T_ALARM_MAP));
|
||
map->mask = RTC_MASK;
|
||
alarm_vm_reset();
|
||
return;
|
||
}
|
||
|
||
for (i = 0; i < M_MAX_ALARM_NUMS; i++) {
|
||
if ((map->map) & BIT(i)) {
|
||
ret = syscfg_read(VM_ALARM_0 + i, &tmp, sizeof(T_ALARM_VM));
|
||
if (ret != sizeof(T_ALARM_VM) || tmp.head != RTC_MASK) {
|
||
alarm_printf("can't find the %d alarm from vm.\n", i);
|
||
memset(&(alarm_tab[i]), 0x00, sizeof(T_ALARM));
|
||
continue;
|
||
}
|
||
|
||
printf("vm info : index=%d, sw=%d, mode=%d, h=%d, m=%d, name_len=%d\n", tmp.alarm.index, tmp.alarm.sw, tmp.alarm.mode, \
|
||
tmp.alarm.time.hour, tmp.alarm.time.min, tmp.alarm.name_len);
|
||
memcpy(&alarm_tab[i], &(tmp.alarm), sizeof(T_ALARM));
|
||
if (alarm_tab[i].sw) {
|
||
map->map_sw |= BIT(i);
|
||
} else {
|
||
map->map_sw &= ~(BIT(i));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
//更新闹钟信息
|
||
static void alarm_vm_write_info_by_index(PT_ALARM_MAP map, u8 index)
|
||
{
|
||
PRINT_FUN();
|
||
s32 ret = 0;
|
||
T_ALARM_VM tmp;
|
||
tmp.head = RTC_MASK;
|
||
memcpy(&(tmp.alarm), &alarm_tab[index], sizeof(T_ALARM));
|
||
tmp.alarm.index = index;
|
||
ret = syscfg_write(VM_ALARM_0 + index, &tmp, sizeof(T_ALARM_VM));
|
||
if (ret != sizeof(T_ALARM_VM)) {
|
||
alarm_printf("The %d alarm write vm err!\n", index);
|
||
return;
|
||
}
|
||
|
||
alarm_printf("vm info : index=%d, sw=%d, mode=%d, h=%d, m=%d, name_len=%d\n", tmp.alarm.index, tmp.alarm.sw, tmp.alarm.mode, \
|
||
tmp.alarm.time.hour, tmp.alarm.time.min, tmp.alarm.name_len);
|
||
alarm_vm_write_mask(map);
|
||
return;
|
||
}
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/*闹钟名字部分代码 */
|
||
/*----------------------------------------------------------------------------*/
|
||
static void alarm_vm_write_name(u8 *p, u8 index)
|
||
{
|
||
PRINT_FUN();
|
||
|
||
s32 ret = 0;
|
||
|
||
ret = syscfg_write(VM_ALARM_NAME_0 + index, p, sizeof(alarm_name));
|
||
if (ret < 0) {
|
||
PRINT_FUN_RETURN_INFO();
|
||
return;
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
static void alarm_vm_read_name(u8 *p, u8 index)
|
||
{
|
||
PRINT_FUN();
|
||
|
||
s32 ret = 0;
|
||
|
||
ret = syscfg_read(VM_ALARM_NAME_0 + index, p, sizeof(alarm_name));
|
||
if (ret < 0) {
|
||
PRINT_FUN_RETURN_INFO();
|
||
return;
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
void alarm_name_clear(void)
|
||
{
|
||
PRINT_FUN();
|
||
memset(alarm_name, 0x00, sizeof(alarm_name));
|
||
return;
|
||
}
|
||
|
||
|
||
void alarm_name_set(u8 *p, u8 index, u8 len)
|
||
{
|
||
PRINT_FUN();
|
||
|
||
if (index > M_MAX_ALARM_INDEX) {
|
||
PRINT_FUN_RETURN_INFO();
|
||
alarm_printf("alarm is full!\n");
|
||
return;
|
||
}
|
||
|
||
|
||
if ((len == 0) || (len > sizeof(alarm_name))) {
|
||
PRINT_FUN_RETURN_INFO();
|
||
return;
|
||
}
|
||
|
||
alarm_name_clear();
|
||
|
||
alarm_printf("alarm name len : %d\n", len);
|
||
alarm_printf_buf(p, len);
|
||
|
||
memcpy(alarm_name, p, len);
|
||
alarm_vm_write_name(alarm_name, index);
|
||
|
||
return;
|
||
}
|
||
|
||
u8 alarm_name_get(u8 *p, u8 index)
|
||
{
|
||
PRINT_FUN();
|
||
|
||
u8 name_len = 0;
|
||
|
||
if (index > M_MAX_ALARM_INDEX) {
|
||
PRINT_FUN_RETURN_INFO();
|
||
return 0;
|
||
}
|
||
|
||
alarm_vm_read_name(alarm_name, index);
|
||
|
||
name_len = alarm_tab[index].name_len;
|
||
memcpy(p, alarm_name, name_len);
|
||
|
||
alarm_printf("alarm name len : %d\n", name_len);
|
||
alarm_printf_buf(alarm_name, name_len);
|
||
|
||
return name_len;
|
||
}
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/*工具函数部分代码 */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief 月份换算为月天数
|
||
@param month,year
|
||
@return 月份天数
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
u16 month_for_day(u8 month, u16 year)
|
||
{
|
||
extern u16 month_to_day(u16 year, u8 month);
|
||
return month_to_day(year, month);
|
||
}
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief 计算未来几天的日期 days要小于29,防止跨两个月
|
||
@param data_time--计算日期
|
||
@return none
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
void rtc_calculate_next_few_day(struct sys_time *data_time, u8 days)
|
||
{
|
||
if (!days || days >= 29) {
|
||
return;
|
||
}
|
||
u16 tmp16 = month_for_day(data_time->month, data_time->year);
|
||
data_time->day += days;
|
||
if (data_time->day > tmp16) {
|
||
data_time->month++;
|
||
data_time->day -= tmp16;
|
||
if (data_time->month > 12) {
|
||
data_time->month = 1;
|
||
data_time->year++;
|
||
}
|
||
}
|
||
}
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/**@brief 日期转换为星期
|
||
@param data_time--日期
|
||
@return 星期
|
||
@note
|
||
*/
|
||
/*----------------------------------------------------------------------------*/
|
||
//蔡勒(Zeller)公式:w=y+[y/4]+[c/4]-2c+[26x(m+1)/10]+d-1
|
||
u8 rtc_calculate_week_val(struct sys_time *data_time)
|
||
{
|
||
struct sys_time t_time;
|
||
u32 century, val, year;
|
||
|
||
memcpy(&t_time, data_time, sizeof(struct sys_time));
|
||
if (t_time.month < 3) {
|
||
t_time.month = t_time.month + 12;
|
||
t_time.year--;
|
||
}
|
||
year = t_time.year % 100;
|
||
century = t_time.year / 100;
|
||
val = year + (year / 4) + (century / 4) + (26 * (t_time.month + 1) / 10) + t_time.day;
|
||
val = val - century * 2 - 1;
|
||
|
||
return (u8)(val % 7);
|
||
}
|
||
|
||
|
||
static int __alarm_cmp_time_num(u32 num1, u32 num2)
|
||
{
|
||
int ret = -2;
|
||
|
||
if (num1 > num2) {
|
||
ret = 1;
|
||
} else if (num1 == num2) {
|
||
ret = 0;
|
||
} else if (num1 < num2) {
|
||
ret = -1;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
/*
|
||
* 函数功能 :比较两个闹钟的时间
|
||
* 函数形参 :time1 - 闹钟1;time2 - 闹钟2
|
||
* 返回值 :0-两闹钟相等;1-闹钟1时间比对比闹钟2要晚;-1-闹钟1比对比闹钟2早 -2-比较出错
|
||
* 备注 :无
|
||
*
|
||
* */
|
||
static int alarm_cmp_time_member(struct sys_time *time1, struct sys_time *time2, TIME_MEMBER_ENUM type)
|
||
{
|
||
switch (type) {
|
||
case TIME_MEMBER_YEAR:
|
||
return __alarm_cmp_time_num(time1->year, time2->year);
|
||
case TIME_MEMBER_MONTH:
|
||
return __alarm_cmp_time_num(time1->month, time2->month);
|
||
case TIME_MEMBER_DAY:
|
||
return __alarm_cmp_time_num(time1->day, time2->day);
|
||
case TIME_MEMBER_HOUR:
|
||
return __alarm_cmp_time_num(time1->hour, time2->hour);
|
||
case TIME_MEMBER_MIN:
|
||
return __alarm_cmp_time_num(time1->min, time2->min);
|
||
case TIME_MEMBER_SEC:
|
||
return __alarm_cmp_time_num(time1->sec, time2->sec);
|
||
|
||
default:
|
||
return -2;
|
||
}
|
||
|
||
return -2;
|
||
}
|
||
|
||
/*
|
||
* 函数功能 :比较两个闹钟的时间
|
||
* 函数形参 :time1 - 闹钟1;time2 - 闹钟2
|
||
* 返回值 :0-两闹钟相等;1-闹钟1时间比对比闹钟2要晚;-1-闹钟1比对比闹钟2早 -2-比较出错
|
||
* 备注 :无
|
||
*
|
||
* */
|
||
static int alarm_cmp_time(struct sys_time *time1, struct sys_time *time2)
|
||
{
|
||
u8 i;
|
||
int ret = 0;
|
||
|
||
for (i = 0; i < TIME_MEMBER_MAX; i++) {
|
||
ret = alarm_cmp_time_member(time1, time2, i);
|
||
if (ret != 0) {
|
||
break;
|
||
}
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/*核心部分代码 */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
|
||
|
||
/*
|
||
** 函数功能 :根据闹钟的模式计算出实际时间
|
||
** 函数形参 :pTime-闹钟时间结构体;week-当下星期; mode-闹钟模式
|
||
** 返回值 :void
|
||
** 备注 :无
|
||
*/
|
||
|
||
static void __alarm_calc_time_by_week_mode(struct sys_time *pTime, u8 mode)
|
||
{
|
||
PRINT_FUN();
|
||
u8 i = 0;
|
||
u8 alarm_week = 0;
|
||
u8 tmp_mode = 0;
|
||
alarm_week = rtc_calculate_week_val(pTime);//alarm_week 可以理解为最近可以设置的闹钟(忽略week)
|
||
if (alarm_week == 0) {
|
||
alarm_week = 7; //星期天写成7,方便对比计算
|
||
}
|
||
|
||
//查找当前可以设置闹钟日期最近的日期
|
||
for (i = 1; i < 8; i++) {
|
||
if (mode & BIT(i)) {
|
||
if (i >= alarm_week) {
|
||
tmp_mode = i;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (i >= 8) {//翻越了星期的
|
||
for (i = 1; i < 8; i++) {
|
||
if (mode & BIT(i)) {
|
||
tmp_mode = i;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if ((tmp_mode >= 1) && (tmp_mode < 8)) {
|
||
if (tmp_mode > alarm_week) {
|
||
alarm_printf("***a***\n");
|
||
//没有翻越星期
|
||
rtc_calculate_next_few_day(pTime, tmp_mode - alarm_week);
|
||
} else if (tmp_mode < alarm_week) {
|
||
//翻越了星期
|
||
alarm_printf("***b***\n");
|
||
rtc_calculate_next_few_day(pTime, 7 - (alarm_week - tmp_mode));
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
/*
|
||
** 函数功能 :根据闹钟的时、分计算出它具体的时间(年、月、日、时、分、秒)
|
||
** 函数形参 :带有时、分和闹钟模式的时间结构体
|
||
** 返回值 :void
|
||
** 备注 :无
|
||
*/
|
||
static void alarm_calc_real_time_by_index(struct sys_time *cTime, u8 index)
|
||
{
|
||
struct sys_time tmp = {0};
|
||
PT_ALARM pAlarm_tab;
|
||
|
||
if (index > M_MAX_ALARM_INDEX) {
|
||
PRINT_FUN_RETURN_INFO();
|
||
return;
|
||
}
|
||
|
||
pAlarm_tab = &(alarm_tab[index]);
|
||
struct sys_time *pTime = &(pAlarm_tab->time);
|
||
|
||
if (pAlarm_tab->mode > M_MAX_ALARM_MODE) {
|
||
PRINT_FUN_RETURN_INFO();
|
||
return;
|
||
}
|
||
u32 c_tmp = ((cTime->hour & 0x1f) << 12) | ((cTime->min & 0x3f) << 6) | (cTime->sec & 0x3f);
|
||
u32 p_tmp = ((pTime->hour & 0x1f) << 12) | ((pTime->min & 0x3f) << 6) | (pTime->sec & 0x3f);
|
||
|
||
if (p_tmp > c_tmp) { //时间未到
|
||
|
||
PRINT_FUN_RETURN_INFO();
|
||
pTime->year = cTime->year;
|
||
pTime->month = cTime->month;
|
||
pTime->day = cTime->day;
|
||
pTime->sec = 0;
|
||
} else {
|
||
PRINT_FUN_RETURN_INFO();
|
||
memcpy(&tmp, cTime, sizeof(struct sys_time));
|
||
rtc_calculate_next_few_day(&tmp, 1);
|
||
pTime->year = tmp.year;
|
||
pTime->month = tmp.month;
|
||
pTime->day = tmp.day;
|
||
pTime->sec = 0;
|
||
|
||
}
|
||
|
||
if ((pAlarm_tab->mode != E_ALARM_MODE_ONCE) && (pAlarm_tab->mode != E_ALARM_MODE_EVERY_DAY)) {
|
||
__alarm_calc_time_by_week_mode(pTime, pAlarm_tab->mode);
|
||
}
|
||
alarm_puts_time(pTime);
|
||
}
|
||
|
||
static void __alarm_get_the_earliest(void)
|
||
{
|
||
PRINT_FUN();
|
||
int ret = 0;
|
||
u8 index = 0;
|
||
u8 i = 0;
|
||
|
||
struct sys_time *pTmp = NULL;
|
||
alarm_map.active_map = 0 ;
|
||
for (i = 0; i < M_MAX_ALARM_NUMS; i++) {
|
||
if (alarm_map.map_sw & BIT(i)) {
|
||
alarm_map.active_map |= BIT(i) ;
|
||
pTmp = &(alarm_tab[i].time);
|
||
index = i;
|
||
break;
|
||
}
|
||
}
|
||
|
||
|
||
if (i >= M_MAX_ALARM_NUMS) {
|
||
alarm_printf("***no alarm***\n");
|
||
alarm_hw_set_sw(0);
|
||
return;
|
||
}
|
||
for (i = index + 1; i < M_MAX_ALARM_NUMS; i++) {
|
||
if (alarm_map.map_sw & BIT(i)) {
|
||
ret = alarm_cmp_time(pTmp, &(alarm_tab[i].time));
|
||
if (0 == ret) {
|
||
alarm_map.active_map |= BIT(i);
|
||
alarm_printf("***A***\n");
|
||
} else if (1 == ret) {
|
||
alarm_printf("***B***\n");
|
||
pTmp = &(alarm_tab[i].time);
|
||
index = i;
|
||
alarm_map.active_map = 0;
|
||
alarm_map.active_map |= BIT(i);
|
||
}
|
||
}
|
||
}
|
||
/* alarm_puts_time(pTmp); */
|
||
/* printf("find the %dth alarm, the save alarm : %x\n", index, alarm_map.active_map); */
|
||
alarm_hw_write_time(pTmp, alarm_tab[index].sw);
|
||
return;
|
||
}
|
||
|
||
|
||
static void __alarm_update_all_time(struct sys_time *cTIME)
|
||
{
|
||
PRINT_FUN();
|
||
u8 i = 0;
|
||
for (i = 0; i < M_MAX_ALARM_NUMS; i++) {
|
||
if (alarm_map.map_sw & BIT(i)) {
|
||
alarm_calc_real_time_by_index(cTIME, i);
|
||
}
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
static void alarm_update()
|
||
{
|
||
PRINT_FUN();
|
||
struct sys_time current_time = {0};
|
||
|
||
if (!is_sys_time_online()) {
|
||
return ;
|
||
}
|
||
|
||
get_sys_time(¤t_time);
|
||
local_irq_disable();
|
||
__alarm_update_all_time(¤t_time);
|
||
local_irq_enable();
|
||
__alarm_get_the_earliest();
|
||
}
|
||
|
||
|
||
u8 alarm_get_active_index(void)
|
||
{
|
||
return alarm_cur_active;
|
||
}
|
||
|
||
u8 alarm_get_info(PT_ALARM p, u8 index)
|
||
{
|
||
u8 ret = E_SUCCESS;
|
||
|
||
local_irq_disable();
|
||
if (alarm_map.map & BIT(index)) {
|
||
p->index = alarm_tab[index].index;
|
||
p->sw = alarm_tab[index].sw;
|
||
p->mode = alarm_tab[index].mode;
|
||
p->time.hour = alarm_tab[index].time.hour;
|
||
p->time.min = alarm_tab[index].time.min;
|
||
p->name_len = alarm_tab[index].name_len;
|
||
} else {
|
||
memset(p, 0x0, sizeof(T_ALARM));
|
||
ret = E_FAILURE;
|
||
}
|
||
local_irq_enable();
|
||
return ret;
|
||
}
|
||
|
||
u8 alarm_get_total(void)
|
||
{
|
||
PRINT_FUN();
|
||
|
||
u8 total = 0;
|
||
u8 i = 0;
|
||
|
||
local_irq_disable();
|
||
for (i = 0; i < M_MAX_ALARM_NUMS; i++) {
|
||
if (alarm_map.map & BIT(i)) {
|
||
total++;
|
||
}
|
||
}
|
||
local_irq_enable();
|
||
alarm_printf("total %d alarm\n", total);
|
||
|
||
return total;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
void rtc_update_time_api(struct sys_time *time)
|
||
{
|
||
if (!is_sys_time_online()) {
|
||
return ;
|
||
}
|
||
set_sys_time(time);
|
||
local_irq_disable();
|
||
__alarm_update_all_time(time);
|
||
local_irq_enable();
|
||
__alarm_get_the_earliest();
|
||
alarm_vm_write_mask(&alarm_map);
|
||
}
|
||
|
||
|
||
void alarm_update_info_after_isr(void)
|
||
{
|
||
PRINT_FUN();
|
||
struct sys_time time = {0};
|
||
|
||
if (!is_sys_time_online()) {
|
||
return ;
|
||
}
|
||
|
||
get_sys_time(&time);
|
||
u8 i = 0;
|
||
printf("alarm_map.active_map =%x\n", alarm_map.active_map);
|
||
local_irq_disable();
|
||
alarm_cur_active = alarm_map.active_map;
|
||
for (i = 0; i < M_MAX_ALARM_NUMS; i++) {
|
||
if (alarm_map.active_map & BIT(i)) {
|
||
if (alarm_tab[i].mode != 0) {
|
||
//闹钟不只响一次
|
||
//计算一次闹钟的时间
|
||
alarm_calc_real_time_by_index(&time, i);
|
||
} else {
|
||
//闹钟只响一次
|
||
alarm_map.map_sw &= ~BIT(i);
|
||
alarm_tab[i].sw = 0;
|
||
alarm_vm_write_info_by_index(&alarm_map, i);
|
||
}
|
||
}
|
||
}
|
||
local_irq_enable();
|
||
__alarm_get_the_earliest();
|
||
alarm_vm_write_mask(&alarm_map);
|
||
}
|
||
|
||
|
||
u8 alarm_add(PT_ALARM p, u8 index)
|
||
{
|
||
|
||
struct sys_time current_time = {0};
|
||
PRINT_FUN();
|
||
u8 ret = E_SUCCESS;
|
||
|
||
if (!is_sys_time_online()) {
|
||
return E_FAILURE;
|
||
}
|
||
|
||
if (index > M_MAX_ALARM_INDEX) {
|
||
PRINT_FUN_RETURN_INFO();
|
||
alarm_printf("alarm is full!\n");
|
||
return E_FAILURE;
|
||
}
|
||
|
||
if (p->mode > M_MAX_ALARM_MODE) {
|
||
PRINT_FUN_RETURN_INFO();
|
||
alarm_printf("alarm's mode is error");
|
||
return E_FAILURE;
|
||
}
|
||
|
||
|
||
local_irq_disable();
|
||
alarm_map.map |= BIT(index);
|
||
if (0 == p->sw) {
|
||
alarm_printf("close the %dth alarm!\n", p->index);
|
||
alarm_map.map_sw &= ~BIT(p->index);
|
||
} else if (1 == p->sw) {
|
||
alarm_printf("set the %dth alarm!\n", p->index);
|
||
alarm_map.map_sw |= BIT(p->index);
|
||
}
|
||
alarm_tab[index].index = p->index;
|
||
alarm_tab[index].sw = p->sw;
|
||
alarm_tab[index].mode = p->mode;
|
||
alarm_tab[index].time.hour = p->time.hour;
|
||
alarm_tab[index].time.min = p->time.min;
|
||
alarm_tab[index].name_len = p->name_len;
|
||
|
||
get_sys_time(¤t_time);
|
||
alarm_calc_real_time_by_index(¤t_time, index);//根据当前时间和闹钟模式计算出最新闹钟时间
|
||
local_irq_enable();
|
||
__alarm_get_the_earliest();
|
||
alarm_vm_write_info_by_index(&alarm_map, index);
|
||
return ret;
|
||
}
|
||
|
||
void alarm_delete(u8 index)
|
||
{
|
||
PRINT_FUN();
|
||
if (index > M_MAX_ALARM_INDEX) {
|
||
PRINT_FUN_RETURN_INFO();
|
||
alarm_printf("alarm is full!\n");
|
||
return;
|
||
}
|
||
alarm_printf("delete the %dth alarm!\n", index);
|
||
|
||
local_irq_disable();
|
||
alarm_map.map &= ~BIT(index);
|
||
alarm_map.map_sw &= ~BIT(index);
|
||
alarm_tab[index].sw = 0;
|
||
local_irq_enable();
|
||
__alarm_get_the_earliest();
|
||
alarm_vm_write_info_by_index(&alarm_map, index);
|
||
return;
|
||
}
|
||
|
||
|
||
void alarm_active_flag_set(u8 flag)
|
||
{
|
||
g_alarm_active_flag = flag;
|
||
|
||
return;
|
||
}
|
||
|
||
u8 alarm_active_flag_get(void)
|
||
{
|
||
return g_alarm_active_flag;
|
||
}
|
||
|
||
static void alarm_check(void *priv)
|
||
{
|
||
extern APP_VAR app_var;
|
||
extern u32 timer_get_ms(void);
|
||
if ((timer_get_ms() - app_var.start_time) > 3000) {
|
||
struct sys_event e;
|
||
e.type = SYS_DEVICE_EVENT;
|
||
e.arg = (void *)DEVICE_EVENT_FROM_ALM;
|
||
e.u.dev.event = DEVICE_EVENT_IN;
|
||
e.u.dev.value = 0;
|
||
sys_event_notify(&e);
|
||
} else {
|
||
sys_timeout_add(NULL, alarm_check, 100);
|
||
}
|
||
}
|
||
|
||
void alarm_init()
|
||
{
|
||
u8 i = 0;
|
||
if (dev_handle) {
|
||
return ;
|
||
}
|
||
dev_handle = dev_open("rtc", NULL);
|
||
if (!dev_handle) {
|
||
ASSERT(0, "%s %d \n", __func__, __LINE__);
|
||
}
|
||
|
||
alarm_vm_read_info(&alarm_map);
|
||
|
||
if (!alarm_active_flag_get()) { //判断是否闹钟在响
|
||
alarm_update();//开机重新写入闹钟寄存器信息
|
||
} else {
|
||
sys_timeout_add(NULL, alarm_check, 100);
|
||
}
|
||
|
||
|
||
/* register_sys_event_handler(SYS_ALL_EVENT, 1, NULL, alarm_event_handler); */
|
||
}
|
||
|
||
#endif //end of RTC_ALM_EN
|
||
#endif
|
||
|
||
|