#ifdef SUPPORT_MS_EXTENSIONS #pragma bss_seg(".alarm_api.data.bss") #pragma data_seg(".alarm_api.data") #pragma const_seg(".alarm_api.text.const") #pragma code_seg(".alarm_api.text") #endif #include "system/includes.h" #include "alarm.h" #include "system/timer.h" #include "app_main.h" #include "tone_player.h" #include "app_task.h" #include "app_config.h" #include "rtc.h" #define LOG_TAG_CONST APP_RTC #define LOG_TAG "[alarm]" #define LOG_ERROR_ENABLE #define LOG_DEBUG_ENABLE #define LOG_INFO_ENABLE #define LOG_DUMP_ENABLE #define LOG_CLI_ENABLE #include "debug.h" #if TCFG_PAY_ALIOS_ENABLE #include "alipay.h" #if ALIPAY_SE_FW_V2_0 #define ALIOS_SYNC_TIME_DONE() #else #define ALIOS_SYNC_TIME_DONE() alipay_vendor_sync_time_done() #endif #endif #if TCFG_APP_RTC_EN #ifdef RTC_ALM_EN /* #define ALARM_DEBUG_EN */ #ifdef ALARM_DEBUG_EN #define alarm_printf log_info #define alarm_putchar log_char #define alarm_printf_buf log_info_hexdump #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__) #define MAX_YEAR 2099 #define MIN_YEAR 2000 /************************************************************* 此文件函数主要是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) 获取闹钟名字 **************************************************************/ struct p11_sys_time { u32 mask; struct sys_time ram_time; /* struct _rtc_trim ram_lrc_trim; */ }; static volatile u8 g_alarm_active_flag = 0; static volatile u8 alarm_cur_active = 0;//当前在响的闹钟 static volatile u8 snooze_time = 10;//单位:分钟 static struct p11_sys_time *p11_rtc_time = 0; typedef struct __alarm_map__ { u32 mask: 16; u32 map : ((M_MAX_ALARM_NUMS + M_MAX_SNOOZE_ALARM_NUM + 7) / 8 * 8); //存储了闹钟数目信息(闹钟数), 第BIT(M_MAX_ALARM_NUMS + 1)为贪睡闹钟 u32 map_sw : ((M_MAX_ALARM_NUMS + M_MAX_SNOOZE_ALARM_NUM + 7) / 8 * 8); //存储闹钟的使能开关(闹钟开关),第BIT(M_MAX_ALARM_NUMS + 1)为贪睡闹钟 u32 active_map : ((M_MAX_ALARM_NUMS + M_MAX_SNOOZE_ALARM_NUM + 7) / 8 * 8); //存储最后激活闹钟,第BIT(M_MAX_ALARM_NUMS + 1)为贪睡闹钟 u8 table[M_MAX_ALARM_NUMS];//闹钟排序 } T_ALARM_MAP, *PT_ALARM_MAP; /* volatile u8 g_alarm_ring_max_cnt = 100; */ static T_ALARM alarm_tab[M_MAX_ALARM_NUMS + M_MAX_SNOOZE_ALARM_NUM] = {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) { /* u32 rets_addr; */ /* __asm__ volatile("%0 = rets ;" : "=r"(rets_addr)); */ /* alarm_printf("%s:0x%x", __func__, rets_addr); */ u8 week = 0; ASSERT(pTime); #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); //cppcheck-suppress unreadVariable week = rtc_calculate_week_val(pTime); #endif alarm_printf("alarm week : %d\n", week); } void alarm_print_all_info(void) { alarm_printf("<%s>:", __func__); alarm_printf("alarm_map.map:%x", alarm_map.map); alarm_printf("alarm_map.map_sw:%x", alarm_map.map_sw); alarm_printf("alarm_map.active_map:%x", alarm_map.active_map); alarm_printf_buf((u8 *)&alarm_map.table, sizeof(alarm_map.table)); for (int i = 0; i < M_MAX_ALARM_NUMS; i++) { alarm_printf_buf((u8 *)&alarm_tab[i], sizeof(T_ALARM)); } } /*----------------------------------------------------------------------------*/ /* rtc 硬化相关代码*/ /*----------------------------------------------------------------------------*/ /* void *is_sys_time_online() */ /* { */ /* return dev_handle; */ /* } */ static void get_sys_time(struct sys_time *time)//获取时间 { ASSERT(time); rtc_read_time(time); } static void set_sys_time(struct sys_time *time)//设置时间 { ASSERT(time); rtc_write_time(time); #if TCFG_PAY_ALIOS_ENABLE ALIOS_SYNC_TIME_DONE(); //更新时间 #endif /* #if TCFG_PAY_ALIOS_ENABLE */ } void alarm_hw_set_sw(u8 sw)//闹钟开关 { /* printf("alarm sw : %d\n", sw); */ rtc_alarm_switch(!!sw); } void alarm_hw_write_time(struct sys_time *time, u8 sw)//写闹钟寄存器 { ASSERT(time); log_info("write_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(!!sw); rtc_write_alarm(time); rtc_debug_dump(); } /*----------------------------------------------------------------------------*/ /* 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)); memset(&map_temp.table, 0xff, M_MAX_ALARM_NUMS); 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 + M_MAX_SNOOZE_ALARM_NUM); 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", i); 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; memset(map->table, 0xff, M_MAX_ALARM_NUMS); 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; } log_info("vm info : index=%d, sw=%d, mode=%d, h=%d, m=%d, sec=%d, name_len=%d\n", tmp.alarm.index, tmp.alarm.sw, tmp.alarm.mode, \ tmp.alarm.time.hour, tmp.alarm.time.min, tmp.alarm.time.sec, 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(); ASSERT(p); 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(); ASSERT(p); 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) { return month_to_day(year, month); } void rtc_calculate_next_few_min(struct sys_time *cur_time, struct sys_time *p_time, u8 min) { if (!min || min >= 60) { return; } ASSERT(cur_time && p_time); memcpy(p_time, cur_time, sizeof(struct sys_time)); p_time->min = cur_time->min + min; if (p_time->min >= 60) { p_time->min -= 60; if (++p_time->hour >= 24) { p_time->hour = 0; if (++p_time->day > month_for_day(p_time->month, p_time->year)) { p_time->day = 1; if (++p_time->month > 12) { p_time->month = 1; if (++p_time->year > MAX_YEAR) { p_time->year = MIN_YEAR; } } } } } /* p_time->sec = 0; */ alarm_puts_time(p_time); } /*----------------------------------------------------------------------------*/ /**@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; } ASSERT(data_time); 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; ASSERT(data_time); 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) { ASSERT(time1 && time2); 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; ASSERT(time1 && time2); 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_snooze_time_by_index(struct sys_time *cTime, u8 index) { PT_ALARM pAlarm_tab; pAlarm_tab = &(alarm_tab[index]); if (index == (M_MAX_ALARM_INDEX + M_MAX_SNOOZE_ALARM_NUM)) {//如果是贪睡闹钟 rtc_calculate_next_few_min(cTime, &pAlarm_tab->time, snooze_time); } } /* ** 函数功能 :根据闹钟的时、分计算出它具体的时间(年、月、日、时、分、秒) ** 函数形参 :带有时、分和闹钟模式的时间结构体 ** 返回值 :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 + M_MAX_SNOOZE_ALARM_NUM) { 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); ASSERT(cTime); 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; u8 index = 0; u8 i = 0; struct sys_time *pTmp = NULL; alarm_map.active_map = 0 ; for (i = 0; i < (M_MAX_ALARM_NUMS + M_MAX_SNOOZE_ALARM_NUM); 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 + M_MAX_SNOOZE_ALARM_NUM)) { alarm_printf("***no alarm***\n"); alarm_hw_set_sw(0); return; } for (i = index + 1; i < (M_MAX_ALARM_NUMS + M_MAX_SNOOZE_ALARM_NUM); 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); log_info("find the %dth alarm, the save alarm : %x\n", index, alarm_map.active_map); alarm_hw_write_time(pTmp, alarm_tab[index].sw); alarm_puts_time(pTmp); alarm_cur_active = alarm_map.active_map; return; } static void __alarm_update_all_time(struct sys_time *cTIME) { PRINT_FUN(); u8 i = 0; ASSERT(cTIME); for (i = 0; i < M_MAX_ALARM_NUMS + M_MAX_SNOOZE_ALARM_NUM; 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}; 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; ASSERT(p); 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) { 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}; get_sys_time(&time); u8 i = 0; log_info("alarm_map.active_map =%x\n", alarm_map.active_map); local_irq_disable(); alarm_cur_active = alarm_map.active_map; /* alarm_calc_snooze_time_by_index(&time, M_MAX_ALARM_NUMS); */ for (i = 0; i < (M_MAX_ALARM_NUMS + M_MAX_SNOOZE_ALARM_NUM); 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; local_irq_enable(); alarm_vm_write_info_by_index(&alarm_map, i); local_irq_disable(); } } } 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 (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(); if (alarm_map.table[index] == 0xff) { int max = -1; for (int i = 0; i < M_MAX_ALARM_NUMS; i++) { if (alarm_map.table[i] != 0xff && alarm_map.table[i] > max) { max = alarm_map.table[i]; } } max++; alarm_map.table[index] = max; } 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].time.sec = p->time.sec; 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(); u8 number; 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(); if (alarm_map.table[index] == 0xff) { local_irq_enable(); log_info("alarm delete manage err \n"); return; } number = alarm_map.table[index]; alarm_map.table[index] = 0xff; for (int i = 0; i < M_MAX_ALARM_NUMS; i++) { if (alarm_map.table[i] != 0xff && alarm_map.table[i] > number) { alarm_map.table[i]--; } } 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_delete_all(void) { u8 flag[M_MAX_ALARM_NUMS] = {0}; PRINT_FUN(); local_irq_disable(); for (int i = 0; i < M_MAX_ALARM_NUMS; i++) { if (alarm_map.table[i] != 0xff) { flag[i] = 1; } alarm_map.table[i] = 0xff; alarm_map.map &= ~BIT(i); alarm_map.map_sw &= ~BIT(i); alarm_tab[i].sw = 0; } local_irq_enable(); __alarm_get_the_earliest(); for (int i = 0; i < M_MAX_ALARM_NUMS; i++) { if (flag[i]) { alarm_vm_write_info_by_index(&alarm_map, i); } } return; } void alarm_snooze() { struct sys_time time = {0}; get_sys_time(&time); alarm_calc_snooze_time_by_index(&time, M_MAX_ALARM_NUMS); local_irq_disable(); alarm_map.map |= BIT(M_MAX_ALARM_NUMS); alarm_map.map_sw |= BIT(M_MAX_ALARM_NUMS); alarm_tab[M_MAX_ALARM_NUMS].sw = 1; local_irq_enable(); __alarm_get_the_earliest(); alarm_vm_write_info_by_index(&alarm_map, M_MAX_ALARM_NUMS); } u8 get_alarm_number2table(u8 num, u8 *table) { u8 idle = 0xff; local_irq_disable(); for (int i = 0; i < M_MAX_ALARM_NUMS; i++) { //printf(">>>>>%s %d\n",__FUNCTION__,alarm_map.table[i]); if (alarm_map.table[i] != 0xff && alarm_map.table[i] == num) { local_irq_enable(); *table = i; return 1; } else if (alarm_map.table[i] == 0xff && idle == 0xff) { idle = i; } } local_irq_enable(); *table = idle; return 0; } 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) { int msg[2]; msg[0] = (u32)DEVICE_EVENT_FROM_ALM; int msec = jiffies_msec2offset(app_var.start_time, jiffies_msec()); if (msec > 3000) { msg[1] = DEVICE_EVENT_IN; app_send_message_from(MSG_FROM_DEVICE, sizeof(msg), msg); } else { sys_timeout_add(NULL, alarm_check, 100); } } #if (defined(CONFIG_CPU_BR28)) int write_p11_sys_time(int param) { struct sys_time cur_time; if (p11_rtc_time) { get_lrc_rtc_trim(&p11_rtc_time->ram_lrc_trim); get_sys_time(&cur_time); memcpy(&p11_rtc_time->ram_time, &cur_time, sizeof(struct sys_time)); p11_rtc_time->mask = 0x12345678; } /* printf("write_p11_sys_time \n"); */ return 0; } static void write_p11_sys_time_by_timer(void *priv) { int argv[3]; argv[0] = (int)write_p11_sys_time; argv[1] = 1; os_taskq_post_type("app_core", Q_CALLBACK, 3, argv); } bool read_p11_sys_time(struct sys_time *t, struct _rtc_trim *lrc_trim) { if (p11_rtc_time && (p11_rtc_time->mask == 0x12345678)) { memcpy(t, &p11_rtc_time->ram_time, sizeof(struct sys_time)); memcpy(lrc_trim, &p11_rtc_time->ram_lrc_trim, sizeof(struct _rtc_trim)); return true; } return false; } void p11_sys_time_init() { ASSERT(P11_HEAP_SIZE >= sizeof(struct sys_time)); //在p11开辟一片空间暂存时间变量 p11_rtc_time = (struct p11_sys_time *)(P11_HEAP_BEGIN + P11_HEAP_SIZE - sizeof(struct p11_sys_time)); sys_s_hi_timer_add(NULL, write_p11_sys_time_by_timer, 2000); } #endif void alarm_init() { alarm_vm_read_info(&alarm_map); if (!alarm_active_flag_get()) { //判断是否闹钟在响 alarm_update();//开机重新写入闹钟寄存器信息 } else { sys_timeout_add(NULL, alarm_check, 100); } //贪睡闹钟部分参数初始化 alarm_tab[M_MAX_ALARM_NUMS].index = M_MAX_ALARM_NUMS; alarm_tab[M_MAX_ALARM_NUMS].sw = 0; alarm_tab[M_MAX_ALARM_NUMS].mode = 0; /* register_sys_event_handler(SYS_ALL_EVENT, 1, NULL, alarm_event_handler); */ } #if TCFG_BT_SUPPORT_MAP static void rtc_get_phone_time_cb(void *p) { if (bt_get_connect_status() != BT_STATUS_WAITINT_CONN) { int error = bt_cmd_prepare(USER_CTRL_MAP_READ_TIME, 0, NULL); log_error("<%s> error:%d", __func__, error); } } static int rtc_get_phone_time_periodically(void) { sys_timer_add(NULL, rtc_get_phone_time_cb, 60 * 60 * 1000); return 0; } late_initcall(rtc_get_phone_time_periodically); #endif /* if TCFG_BT_SUPPORT_MAP */ #endif //end of RTC_ALM_EN #endif