1118 lines
30 KiB
C
1118 lines
30 KiB
C
#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
|
||
|
||
|