在逗猫棒的基础上实现蓝牙转USB功能,目前功能已经实现,还需裁剪掉之前逗猫棒的业务程序
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
#ifndef __ALARM_H__
|
||||
#define __ALARM_H__
|
||||
|
||||
|
||||
//#define RTC_ALM_EN 1
|
||||
#include "typedef.h"
|
||||
#include "system/includes.h"
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct _RTC_TIME {
|
||||
u16 dYear; ///<年份
|
||||
u8 bMonth; ///<月份
|
||||
u8 bDay; ///<天数
|
||||
u8 bHour; ///<时
|
||||
u8 bMin; ///<分
|
||||
u8 bSec; ///<秒
|
||||
// u8 bWeekday; ///<星期几
|
||||
} RTC_TIME;
|
||||
#pragma pack()
|
||||
|
||||
typedef struct __ALARM__ {
|
||||
u8 index;
|
||||
u8 sw;
|
||||
u8 mode;
|
||||
struct sys_time time;
|
||||
u8 name_len;
|
||||
} T_ALARM, *PT_ALARM;
|
||||
|
||||
typedef struct __alarm_vm__ {
|
||||
u16 head;
|
||||
T_ALARM alarm;
|
||||
} T_ALARM_VM, *PT_ALARM_VM;
|
||||
|
||||
enum {
|
||||
E_ALARM_WRITE_VM_ERR = 0x00,
|
||||
E_ALARM_WRITE_VM_SUCC,
|
||||
};
|
||||
|
||||
enum {
|
||||
E_ALARM_MODE_ONCE = 0x00,
|
||||
E_ALARM_MODE_EVERY_DAY = 0x01,
|
||||
E_ALARM_MODE_EVERY_MONDAY = 0x02,
|
||||
E_ALARM_MODE_EVERY_TUESDAY = 0x04,
|
||||
E_ALARM_MODE_EVERY_WEDNESDAY = 0x08,
|
||||
E_ALARM_MODE_EVERY_THURSDAY = 0x10,
|
||||
E_ALARM_MODE_EVERY_FRIDAY = 0x20,
|
||||
E_ALARM_MODE_EVERY_SATURDAY = 0x40,
|
||||
E_ALARM_MODE_EVERY_SUNDAY = 0x80,
|
||||
};
|
||||
|
||||
enum {
|
||||
|
||||
E_WEEK_MONDAY = 0x01,
|
||||
E_WEEK_TUESDAY,
|
||||
E_WEEK_WEDNESDAY,
|
||||
E_WEEK_THURSDAY,
|
||||
E_WEEK_FRIDAY,
|
||||
E_WEEK_SATURDAY,
|
||||
E_WEEK_SUNDAY,
|
||||
};
|
||||
|
||||
|
||||
typedef enum {
|
||||
TIME_MEMBER_YEAR = 0x0,
|
||||
TIME_MEMBER_MONTH,
|
||||
TIME_MEMBER_DAY,
|
||||
TIME_MEMBER_HOUR,
|
||||
TIME_MEMBER_MIN,
|
||||
TIME_MEMBER_SEC,
|
||||
TIME_MEMBER_MAX,
|
||||
} TIME_MEMBER_ENUM;
|
||||
|
||||
|
||||
enum {
|
||||
E_SUCCESS = 0x00,
|
||||
E_FAILURE,
|
||||
};
|
||||
|
||||
/* macro */
|
||||
#define M_MAX_ALARM_NUMS 5
|
||||
#define M_MAX_ALARM_NAME_LEN 32
|
||||
|
||||
#define M_MAX_ALARM_INDEX (M_MAX_ALARM_NUMS-1)
|
||||
#define M_MAX_ALARM_MODE (0xFE)
|
||||
|
||||
|
||||
void alarm_init();
|
||||
u8 alarm_get_info(PT_ALARM p, u8 index);
|
||||
void rtc_update_time_api(struct sys_time *time);
|
||||
void alarm_ring_start();
|
||||
void alarm_active_flag_set(u8 flag);
|
||||
u8 alarm_active_flag_get(void);
|
||||
u8 rtc_calculate_week_val(struct sys_time *data_time);
|
||||
void rtc_calculate_next_few_day(struct sys_time *data_time, u8 days); //未来几天的日期
|
||||
u16 month_for_day(u8 month, u16 year);
|
||||
void *is_sys_time_online();
|
||||
void alarm_update_info_after_isr(void);
|
||||
void alarm_event_handler(struct sys_event *event, void *priv);
|
||||
u8 alarm_add(PT_ALARM p, u8 index);
|
||||
|
||||
#endif //end of __ALARM_H__
|
||||
|
||||
|
||||
@@ -0,0 +1,961 @@
|
||||
#include "system/includes.h"
|
||||
#include "system/timer.h"
|
||||
#include "app_main.h"
|
||||
#include "tone_player.h"
|
||||
#include "app_task.h"
|
||||
#include "alarm.h"
|
||||
#include "app_config.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;
|
||||
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 (!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 user_check_default_time()
|
||||
{
|
||||
struct sys_time current_time;
|
||||
get_sys_time(¤t_time);
|
||||
|
||||
if(current_time.year < 2025 || current_time.year > 2098){
|
||||
printf("current_time.year111 == %d\n",current_time.year);
|
||||
set_rtc_default_time(¤t_time);
|
||||
rtc_update_time_api(¤t_time);
|
||||
}
|
||||
else if(current_time.month < 1 || current_time.month > 12){
|
||||
printf("current_time.year222 == %d\n",current_time.year);
|
||||
set_rtc_default_time(¤t_time);
|
||||
rtc_update_time_api(¤t_time);
|
||||
}
|
||||
else if(current_time.day < 1 || current_time.day > 31){
|
||||
printf("current_time.year333 == %d\n",current_time.year);
|
||||
set_rtc_default_time(¤t_time);
|
||||
rtc_update_time_api(¤t_time);
|
||||
}
|
||||
else if(current_time.hour < 0 || current_time.hour > 23){
|
||||
printf("current_time.year444 == %d\n",current_time.year);
|
||||
set_rtc_default_time(¤t_time);
|
||||
rtc_update_time_api(¤t_time);
|
||||
}
|
||||
else if(current_time.min < 0 || current_time.min > 59){
|
||||
printf("current_time.year555 == %d\n",current_time.year);
|
||||
set_rtc_default_time(¤t_time);
|
||||
rtc_update_time_api(¤t_time);
|
||||
}
|
||||
else if(current_time.sec < 0 || current_time.sec > 59){
|
||||
printf("current_time.year666 == %d\n",current_time.year);
|
||||
set_rtc_default_time(¤t_time);
|
||||
rtc_update_time_api(¤t_time);
|
||||
}
|
||||
else{
|
||||
|
||||
}
|
||||
}
|
||||
void alarm_init()
|
||||
{
|
||||
u8 i = 0;
|
||||
if (dev_handle) {
|
||||
return ;
|
||||
}
|
||||
dev_handle = dev_open("rtc", NULL);
|
||||
user_check_default_time();
|
||||
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
|
||||
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
#include "system/includes.h"
|
||||
#include "alarm.h"
|
||||
#include "system/timer.h"
|
||||
#include "app_main.h"
|
||||
#include "tone_player.h"
|
||||
#include "app_task.h"
|
||||
#include "btstack/avctp_user.h"
|
||||
#include "app_config.h"
|
||||
|
||||
#if 0//TCFG_APP_RTC_EN
|
||||
|
||||
#define ALARM_RING_MAX 50
|
||||
volatile u16 g_alarm_ring_cnt = 0;
|
||||
static u16 g_alarm_dly_tmr = 0;
|
||||
static u16 g_ring_playing_timer = 0;
|
||||
|
||||
extern u8 get_switch_to_rtc_reason();
|
||||
|
||||
/*************************************************************
|
||||
此文件函数主要是用户主要修改的文件
|
||||
|
||||
void set_rtc_default_time(struct sys_time *t)
|
||||
设置默认时间的函数
|
||||
|
||||
void alm_wakeup_isr(void)
|
||||
闹钟到达的函数
|
||||
|
||||
void alarm_event_handler(struct sys_event *event, void *priv)
|
||||
监听按键消息接口,应用于随意按键停止闹钟
|
||||
|
||||
|
||||
int alarm_sys_event_handler(struct sys_event *event)
|
||||
闹钟到达响应接口
|
||||
|
||||
void alarm_ring_start()
|
||||
闹钟铃声播放接口
|
||||
|
||||
|
||||
void alarm_stop(void)
|
||||
闹钟铃声停止播放接口
|
||||
**************************************************************/
|
||||
|
||||
static u8 rtc_can_run(void)
|
||||
{
|
||||
u8 call_status = get_call_status();
|
||||
if ((call_status == BT_CALL_ACTIVE) ||
|
||||
(call_status == BT_CALL_OUTGOING) ||
|
||||
(call_status == BT_CALL_ALERT) ||
|
||||
(call_status == BT_CALL_INCOMING)) {
|
||||
//通话过程不允许开rtc
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void set_rtc_default_time(struct sys_time *t)
|
||||
{
|
||||
t->year = 2019;
|
||||
t->month = 5;
|
||||
t->day = 5;
|
||||
t->hour = 18;
|
||||
t->min = 18;
|
||||
t->sec = 18;
|
||||
}
|
||||
|
||||
|
||||
__attribute__((weak))
|
||||
u8 rtc_app_alarm_ring_play(u8 alarm_state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void alm_wakeup_isr(void)
|
||||
{
|
||||
if (!is_sys_time_online()) {
|
||||
alarm_active_flag_set(true);
|
||||
} else {
|
||||
alarm_active_flag_set(true);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void alarm_ring_cnt_clear(void)
|
||||
{
|
||||
g_alarm_ring_cnt = 0;
|
||||
}
|
||||
|
||||
void alarm_stop(void)
|
||||
{
|
||||
u32 rets_addr;
|
||||
__asm__ volatile("%0 = rets ;" : "=r"(rets_addr));
|
||||
printf("ALARM_STOP : 0x%x !!!\n", rets_addr);
|
||||
alarm_active_flag_set(0);
|
||||
alarm_ring_cnt_clear();
|
||||
rtc_app_alarm_ring_play(0);
|
||||
}
|
||||
|
||||
void alarm_play_timer_del(void)
|
||||
{
|
||||
if (g_ring_playing_timer) {
|
||||
sys_timeout_del(g_ring_playing_timer);
|
||||
g_ring_playing_timer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void __alarm_ring_play(void *p)
|
||||
{
|
||||
if (g_alarm_ring_cnt > 0) {
|
||||
u8 app = app_get_curr_task();
|
||||
if (app != APP_RTC_TASK) {
|
||||
alarm_stop();
|
||||
printf("...not in rtc task\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!tone_get_status()) {
|
||||
if (!rtc_app_alarm_ring_play(1)) {
|
||||
//tone_play_by_path(tone_table[IDEX_TONE_NORMAL], 0);
|
||||
g_alarm_ring_cnt--;
|
||||
}
|
||||
}
|
||||
g_ring_playing_timer = sys_timeout_add(NULL, __alarm_ring_play, 500);
|
||||
} else {
|
||||
if (alarm_active_flag_get()) {
|
||||
// alarm_stop();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void alarm_ring_start()
|
||||
{
|
||||
if (g_alarm_ring_cnt == 0) {
|
||||
g_alarm_ring_cnt = ALARM_RING_MAX;
|
||||
sys_timeout_add(NULL, __alarm_ring_play, 500);
|
||||
}
|
||||
}
|
||||
|
||||
void alarm_event_handler(struct sys_event *event, void *priv)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
SYS_EVENT_HANDLER(SYS_KEY_EVENT, alarm_event_handler, 2);
|
||||
|
||||
static void alarm_dly_play_deal(u32 event_arg)
|
||||
{
|
||||
u8 alm_flag = alarm_active_flag_get();
|
||||
if (rtc_can_run() || (!alm_flag)) {
|
||||
sys_timer_del(g_alarm_dly_tmr);
|
||||
g_alarm_dly_tmr = NULL;
|
||||
if (alm_flag) {
|
||||
//app_task_switch_to(APP_RTC_TASK);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int alarm_sys_event_handler(struct sys_event *event)
|
||||
{
|
||||
struct application *cur;
|
||||
if ((u32)event->arg == DEVICE_EVENT_FROM_ALM) {
|
||||
if (event->u.dev.event == DEVICE_EVENT_IN) {
|
||||
printf("alarm_sys_event_handler\n");
|
||||
alarm_update_info_after_isr();
|
||||
|
||||
u8 app = app_get_curr_task();
|
||||
if (app == APP_RTC_TASK) {
|
||||
alarm_ring_start();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!rtc_can_run()) {
|
||||
if (g_alarm_dly_tmr == 0) {
|
||||
g_alarm_dly_tmr = sys_timer_add((event->arg), alarm_dly_play_deal, 500);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
#include "app_config.h"
|
||||
#include "key_event_deal.h"
|
||||
#include "system/includes.h"
|
||||
#include "tone_player.h"
|
||||
#include "app_task.h"
|
||||
#include "tone_player.h"
|
||||
#include "media/includes.h"
|
||||
#include "system/sys_time.h"
|
||||
#include "alarm.h"
|
||||
#include "clock_cfg.h"
|
||||
|
||||
|
||||
/*************************************************************
|
||||
此文件函数主要是rtc模式按键处理和事件处理
|
||||
|
||||
**************************************************************/
|
||||
|
||||
|
||||
#if TCFG_APP_RTC_EN
|
||||
|
||||
|
||||
|
||||
#define LOG_TAG_CONST APP_RTC
|
||||
#define LOG_TAG "[APP_RTC]"
|
||||
#define LOG_ERROR_ENABLE
|
||||
#define LOG_DEBUG_ENABLE
|
||||
#define LOG_INFO_ENABLE
|
||||
/* #define LOG_DUMP_ENABLE */
|
||||
#define LOG_CLI_ENABLE
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
struct rtc_opr {
|
||||
void *dev_handle;
|
||||
u8 rtc_set_mode;
|
||||
u8 rtc_pos;
|
||||
u8 alm_enable;
|
||||
u8 alm_num;
|
||||
struct sys_time set_time;
|
||||
};
|
||||
|
||||
|
||||
static struct rtc_opr *__this = NULL;
|
||||
static u8 switch_to_rtc_reason = 0;
|
||||
|
||||
|
||||
static void rtc_app_init()
|
||||
{
|
||||
if (!__this) {
|
||||
__this = zalloc(sizeof(struct rtc_opr));
|
||||
ASSERT(__this, "%s %di \n", __func__, __LINE__);
|
||||
__this->dev_handle = dev_open("rtc", NULL);
|
||||
if (!__this->dev_handle) {
|
||||
ASSERT(0, "%s %d \n", __func__, __LINE__);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief rtc 退出
|
||||
@param 无
|
||||
@return
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void rtc_task_close()
|
||||
{
|
||||
if (__this) {
|
||||
if (__this->dev_handle) {
|
||||
dev_close(__this->dev_handle);
|
||||
__this->dev_handle = NULL;
|
||||
}
|
||||
free(__this);
|
||||
__this = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief rtc 启动
|
||||
@param 无
|
||||
@return
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void rtc_task_start()
|
||||
{
|
||||
rtc_app_init();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//*----------------------------------------------------------------------------*/
|
||||
/**@brief rtc 主任务
|
||||
@param 无
|
||||
@return 无
|
||||
@note
|
||||
*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void app_rtc_task()
|
||||
{
|
||||
rtc_task_start();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
|
||||
void app_rtc_task()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,358 @@
|
||||
#include "app_config.h"
|
||||
#include "alarm.h"
|
||||
#include "app_action.h"
|
||||
#include "system/includes.h"
|
||||
#include "clock_cfg.h"
|
||||
#include "ioctl_cmds.h"
|
||||
#include "system/sys_time.h"
|
||||
|
||||
#if (TCFG_APP_RTC_EN && TCFG_USE_VIRTUAL_RTC)
|
||||
|
||||
|
||||
/*************************************************************
|
||||
此文件函数主要是虚拟rtc设备的实现
|
||||
应用于不外挂晶振的场景,用户可以忽略实现,
|
||||
最后的应用的接口与挂晶振的接口一致
|
||||
**************************************************************/
|
||||
|
||||
|
||||
#define WRITE_ALARM BIT(1)
|
||||
#define READ_ALARM BIT(5)
|
||||
|
||||
#define WRITE_RTC BIT(0)
|
||||
#define READ_RTC BIT(4)
|
||||
|
||||
#define MAX_YEAR 2099
|
||||
#define MIN_YEAR 2000
|
||||
|
||||
|
||||
typedef struct _RTC_SIMULATE_VAR {
|
||||
u16 crc;
|
||||
struct device device;
|
||||
struct sys_time sys_simulate_time;
|
||||
struct sys_time sys_alarm_time;
|
||||
/* OS_MUTEX mutex; */
|
||||
} RTC_SIMULATE_VAR;
|
||||
|
||||
#define __this (&rtc_smulate_var)
|
||||
static RTC_SIMULATE_VAR rtc_smulate_var sec(.vir_rtc) = {
|
||||
.crc = 0xffff,
|
||||
};
|
||||
|
||||
static u8 g_alarm_flag = 0;
|
||||
static u64 sum_nsec = 0;
|
||||
|
||||
|
||||
static void write_alarm(struct sys_time *alarm_time);
|
||||
void set_alarm_default_time(struct sys_time *t)
|
||||
{
|
||||
t->year = 2019;
|
||||
t->month = 1;
|
||||
t->day = 1;
|
||||
t->hour = 18;
|
||||
t->min = 19;
|
||||
t->sec = 00;
|
||||
write_alarm(t);
|
||||
}
|
||||
__attribute__((weak))void alm_wakeup_isr(void);
|
||||
__attribute__((weak)) void set_rtc_default_time(struct sys_time *t);
|
||||
u8 rtc_get_time_vm();
|
||||
u8 rtc_save_time_vm();
|
||||
u8 rtc_get_alm_vm();
|
||||
u8 rtc_save_alm_vm();
|
||||
|
||||
static u8 is_the_same_time(struct sys_time *time1, struct sys_time *time2)
|
||||
{
|
||||
return (time1->year == time2->year &&
|
||||
time1->month == time2->month &&
|
||||
time1->day == time2->day &&
|
||||
time1->hour == time2->hour &&
|
||||
time1->min == time2->min &&
|
||||
time1->sec == time2->sec);
|
||||
}
|
||||
|
||||
|
||||
static int rtc_simulate_init(const struct dev_node *node, void *arg)
|
||||
{
|
||||
if (power_return_flag()) {
|
||||
/* os_mutex_create(&__this->mutex); */
|
||||
if (0) {
|
||||
|
||||
} else if (set_rtc_default_time) {
|
||||
set_rtc_default_time(&__this->sys_simulate_time);
|
||||
} else {
|
||||
__this->sys_simulate_time.year = 2020;
|
||||
__this->sys_simulate_time.month = 1;
|
||||
__this->sys_simulate_time.day = 1;
|
||||
__this->sys_simulate_time.hour = 0;
|
||||
__this->sys_simulate_time.min = 0;
|
||||
__this->sys_simulate_time.sec = 0;
|
||||
}
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
rtc_get_alm_vm();
|
||||
rtc_save_time_vm();
|
||||
|
||||
printf("rtc_simulate_init: %d-%d-%d %d:%d:%d\n",
|
||||
__this->sys_simulate_time.year,
|
||||
__this->sys_simulate_time.month,
|
||||
__this->sys_simulate_time.day,
|
||||
__this->sys_simulate_time.hour,
|
||||
__this->sys_simulate_time.min,
|
||||
__this->sys_simulate_time.sec);
|
||||
|
||||
/* set_alarm_default_time(&__this->sys_alarm_time); */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtc_simulate_open(const char *name, struct device **device, void *arg)
|
||||
{
|
||||
*device = &__this->device;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void write_alarm(struct sys_time *alarm_time)
|
||||
{
|
||||
local_irq_disable();
|
||||
memcpy(&__this->sys_alarm_time, alarm_time, sizeof(struct sys_time));
|
||||
rtc_save_alm_vm();
|
||||
local_irq_enable();
|
||||
}
|
||||
|
||||
static void read_alarm(struct sys_time *alarm_time)
|
||||
{
|
||||
local_irq_disable();
|
||||
rtc_get_alm_vm();
|
||||
memcpy(alarm_time, &__this->sys_alarm_time, sizeof(struct sys_time));
|
||||
local_irq_enable();
|
||||
}
|
||||
|
||||
static void write_sys_time(struct sys_time *curr_time)
|
||||
{
|
||||
local_irq_disable();
|
||||
memcpy(&__this->sys_simulate_time, curr_time, sizeof(struct sys_time));
|
||||
local_irq_enable();
|
||||
}
|
||||
|
||||
static void read_sys_time(struct sys_time *curr_time)
|
||||
{
|
||||
local_irq_disable();
|
||||
memcpy(curr_time, &__this->sys_simulate_time, sizeof(struct sys_time));
|
||||
local_irq_enable();
|
||||
}
|
||||
|
||||
static void set_alarm_ctrl(u8 set_alarm)
|
||||
{
|
||||
g_alarm_flag = set_alarm;
|
||||
}
|
||||
|
||||
static int rtc_simulate_ioctl(struct device *device, u32 cmd, u32 arg)
|
||||
{
|
||||
int err = 0;
|
||||
switch (cmd) {
|
||||
case IOCTL_SET_ALARM:
|
||||
write_alarm((struct sys_time *)arg);
|
||||
break;
|
||||
case IOCTL_GET_ALARM:
|
||||
read_alarm((struct sys_time *)arg);
|
||||
break;
|
||||
case IOCTL_SET_ALARM_ENABLE:
|
||||
if (arg) {
|
||||
set_alarm_ctrl(1);
|
||||
} else {
|
||||
set_alarm_ctrl(0);
|
||||
}
|
||||
break;
|
||||
case IOCTL_GET_SYS_TIME:
|
||||
read_sys_time((struct sys_time *)arg);
|
||||
break;
|
||||
case IOCTL_SET_SYS_TIME:
|
||||
write_sys_time((struct sys_time *)arg);
|
||||
break;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
u8 rtc_save_time_vm()
|
||||
{
|
||||
u8 ret = syscfg_write(VM_VIR_RTC_TIME, &__this->sys_simulate_time, sizeof(struct sys_time));
|
||||
return ret;
|
||||
}
|
||||
|
||||
u8 rtc_get_time_vm()
|
||||
{
|
||||
u8 ret = syscfg_read(VM_VIR_RTC_TIME, &__this->sys_simulate_time, sizeof(struct sys_time));
|
||||
return ret;
|
||||
}
|
||||
|
||||
u8 rtc_save_alm_vm()
|
||||
{
|
||||
u8 ret = syscfg_write(VM_VIR_ALM_TIME, &__this->sys_alarm_time, sizeof(struct sys_time));
|
||||
return ret;
|
||||
}
|
||||
|
||||
u8 rtc_get_alm_vm()
|
||||
{
|
||||
u8 ret = syscfg_read(VM_VIR_ALM_TIME, &__this->sys_alarm_time, sizeof(struct sys_time));
|
||||
return ret;
|
||||
}
|
||||
|
||||
u8 rtc_get_sum_nsec_vm()
|
||||
{
|
||||
u8 ret = syscfg_read(VM_VIR_SUM_NSEC, &sum_nsec, 8);
|
||||
return ret;
|
||||
}
|
||||
|
||||
u8 rtc_save_sum_nsec_vm()
|
||||
{
|
||||
u8 ret = syscfg_read(VM_VIR_SUM_NSEC, &sum_nsec, 8);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void set_virtual_rtc_tick(u64 actual_ns)
|
||||
{
|
||||
#if (defined(TCFG_USE_VIRTUAL_RTC) && (TCFG_USE_VIRTUAL_RTC))
|
||||
struct sys_time temp_time;
|
||||
static u8 cal_flag = 0;
|
||||
|
||||
sum_nsec += actual_ns;
|
||||
if (sum_nsec >= 1000000000) {
|
||||
sum_nsec -= 1000000000;
|
||||
cal_flag = 1;
|
||||
}
|
||||
|
||||
if (cal_flag) {
|
||||
cal_flag = 0;
|
||||
read_sys_time(&temp_time);
|
||||
if (++temp_time.sec >= 60) {
|
||||
temp_time.sec = 0;
|
||||
if (++temp_time.min >= 60) {
|
||||
temp_time.min = 0;
|
||||
if (++temp_time.hour >= 24) {
|
||||
temp_time.hour = 0;
|
||||
if (++temp_time.day > month_for_day(temp_time.month, temp_time.year)) {
|
||||
temp_time.day = 1;
|
||||
if (++temp_time.month > 12) {
|
||||
temp_time.month = 1;
|
||||
if (++temp_time.year > MAX_YEAR) {
|
||||
temp_time.year = MIN_YEAR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
write_sys_time(&temp_time);
|
||||
/* printf("rtc_sys_time: %d-%d-%d %d:%d:%d\n", */
|
||||
/* temp_time.year, */
|
||||
/* temp_time.month, */
|
||||
/* temp_time.day, */
|
||||
/* temp_time.hour, */
|
||||
/* temp_time.min, */
|
||||
/* temp_time.sec); */
|
||||
|
||||
local_irq_disable();
|
||||
/* rtc_get_alm_vm(); */
|
||||
if (g_alarm_flag && is_the_same_time(&__this->sys_alarm_time, &__this->sys_simulate_time)) {
|
||||
local_irq_enable();
|
||||
if (alm_wakeup_isr) {
|
||||
alm_wakeup_isr();
|
||||
}
|
||||
} else {
|
||||
local_irq_enable();
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
extern void vir_rtc_get_actual_time(u64 *actual_time);
|
||||
void vir_rtc_trim()
|
||||
{
|
||||
u64 actual_time;
|
||||
vir_rtc_get_actual_time(&actual_time);
|
||||
u32 sec = actual_time / 1000000000;
|
||||
u32 min = sec / 60;
|
||||
sec = sec % 60;
|
||||
u32 hour = min / 60;
|
||||
min = min % 60;
|
||||
|
||||
struct sys_time temp_time;
|
||||
rtc_get_time_vm();
|
||||
read_sys_time(&temp_time);
|
||||
temp_time.sec += sec;
|
||||
if (temp_time.sec >= 60) {
|
||||
temp_time.min++;
|
||||
temp_time.sec -= 60;
|
||||
}
|
||||
temp_time.min += min;
|
||||
if (temp_time.min >= 60) {
|
||||
temp_time.hour++;
|
||||
temp_time.min -= 60;
|
||||
}
|
||||
temp_time.hour += hour;
|
||||
if (temp_time.hour >= 24) {
|
||||
temp_time.day++;
|
||||
temp_time.hour -= 24;
|
||||
if (temp_time.day > month_for_day(temp_time.month, temp_time.year)) {
|
||||
temp_time.day = 1;
|
||||
if (++temp_time.month > 12) {
|
||||
temp_time.month = 1;
|
||||
if (++temp_time.year > MAX_YEAR) {
|
||||
temp_time.year = MIN_YEAR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
write_sys_time(&temp_time);
|
||||
rtc_get_sum_nsec_vm();
|
||||
set_virtual_rtc_tick(actual_time % 1000000000);
|
||||
printf("rtc_sys_time: %d-%d-%d %d:%d:%d\n",
|
||||
temp_time.year,
|
||||
temp_time.month,
|
||||
temp_time.day,
|
||||
temp_time.hour,
|
||||
temp_time.min,
|
||||
temp_time.sec);
|
||||
}
|
||||
|
||||
u32 alm_trans_for_sec()
|
||||
{
|
||||
struct sys_time temp_time;
|
||||
struct sys_time alm_time;
|
||||
|
||||
read_alarm(&alm_time);
|
||||
u16 alm_day = ymd_to_day(&__this->sys_alarm_time);
|
||||
|
||||
/* rtc_get_time_vm(); */
|
||||
read_sys_time(&temp_time);
|
||||
u16 cur_day = ymd_to_day(&temp_time);
|
||||
|
||||
u32 alm_tmp = (alm_day << 17) | ((__this->sys_alarm_time.hour & 0x1f) << 12) | ((__this->sys_alarm_time.min & 0x3f) << 6) | (__this->sys_alarm_time.sec & 0x3f);
|
||||
u32 cur_tmp = (cur_day << 17) | ((temp_time.hour & 0x1f) << 12) | ((temp_time.min & 0x3f) << 6) | (temp_time.sec & 0x3f);
|
||||
if (alm_tmp < cur_tmp) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 day = alm_day - cur_day;
|
||||
u32 hour = __this->sys_alarm_time.hour + day * 24 - temp_time.hour;
|
||||
u32 min = __this->sys_alarm_time.min + hour * 60 - temp_time.min;
|
||||
u32 sec = __this->sys_alarm_time.sec + min * 60 - temp_time.sec;
|
||||
/* printf("alm_sec = %d\n", sec); */
|
||||
return sec;
|
||||
}
|
||||
|
||||
|
||||
const struct device_operations rtc_simulate_ops = {
|
||||
.init = rtc_simulate_init,
|
||||
.open = rtc_simulate_open,
|
||||
.ioctl = rtc_simulate_ioctl,
|
||||
.read = NULL,
|
||||
.write = NULL,
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user