在逗猫棒的基础上实现蓝牙转USB功能,目前功能已经实现,还需裁剪掉之前逗猫棒的业务程序

This commit is contained in:
2026-07-24 11:41:08 +08:00
commit b3f06697a6
1569 changed files with 515355 additions and 0 deletions
+103
View File
@@ -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__
+961
View File
@@ -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 monthyear
@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 - 闹钟1time2 - 闹钟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 - 闹钟1time2 - 闹钟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(&current_time);
local_irq_disable();
__alarm_update_all_time(&current_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(&current_time);
alarm_calc_real_time_by_index(&current_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(&current_time);
if(current_time.year < 2025 || current_time.year > 2098){
printf("current_time.year111 == %d\n",current_time.year);
set_rtc_default_time(&current_time);
rtc_update_time_api(&current_time);
}
else if(current_time.month < 1 || current_time.month > 12){
printf("current_time.year222 == %d\n",current_time.year);
set_rtc_default_time(&current_time);
rtc_update_time_api(&current_time);
}
else if(current_time.day < 1 || current_time.day > 31){
printf("current_time.year333 == %d\n",current_time.year);
set_rtc_default_time(&current_time);
rtc_update_time_api(&current_time);
}
else if(current_time.hour < 0 || current_time.hour > 23){
printf("current_time.year444 == %d\n",current_time.year);
set_rtc_default_time(&current_time);
rtc_update_time_api(&current_time);
}
else if(current_time.min < 0 || current_time.min > 59){
printf("current_time.year555 == %d\n",current_time.year);
set_rtc_default_time(&current_time);
rtc_update_time_api(&current_time);
}
else if(current_time.sec < 0 || current_time.sec > 59){
printf("current_time.year666 == %d\n",current_time.year);
set_rtc_default_time(&current_time);
rtc_update_time_api(&current_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
+194
View File
@@ -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
+118
View File
@@ -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
+358
View File
@@ -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