mcu_ab568x/app/projects/AB5682C_128/functions/func_bt_call.c
2025-05-30 18:03:10 +08:00

481 lines
16 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "include.h"
#include "func.h"
#include "func_bt.h"
#include "m_rtc.h"
#include "app_variable.h"
#define VOLUME_BAR_TIME_MAX 2000 // 音量条显示时长unit:ms
#define VOLUME_BAR_ANIM_TIME_MAX 10 // 音量条淡入淡出unit:ms
#define ANIMATION_TICK_EXPIRE 20 // 动画帧间隔unit:ms
#define ANIMATION_ROTATION_ANGLE (3600 / 100) // 单次旋转角度
#define ANIMATION_ICON_SIZE_MIN 48 // 图标缩放最小尺寸
#define ANIMATION_ICON_SIZE_MAX 80 // 图标缩放最大尺寸
enum {
COMPO_ID_TXT_NUMBER = 0xff, //避免id被覆盖
COMPO_ID_CALL_ICON,
COMPO_ID_TXT_TIME,
COMPO_ID_BTN_REJECT,
// COMPO_ID_BTN_MIC,
COMPO_ID_CALL_VOLUME,
COMPO_ID_CALL_VOLUME_BG,
};
typedef struct f_bt_call_t_ {
bool sta; //0:呼出(outgoing); 1:通话(call);
// u16 times; //通话秒数
char call_time_str[16]; //通话计时字符串
u32 clcc_tick; //主动查询号码计时
u32 exit_tick; //页面退出计时
u32 sco_tick;
u8 hours;
u8 minutes;
u8 seconds;
u16 anim_angle;
u32 anim_tick;
u8 vol_hfp; // 临时音量
u8 vol_gradually; // 音量条淡入淡出1:淡入2淡出
s16 vol_alpha; // 音量条透明度
bool vol_show; // 音量条显示标志
u32 amin_tick; // 音量条动画Tick
u32 vol_show_tick; // 音量条Tick
} f_bt_call_t;
static void func_bt_call_back_to(void)
{
u8 last_func = func_directly_back_to();
if (last_func == FUNC_BT_RING) {
func_directly_back_to();
}
}
extern struct Phone_Time_t phone_time;
extern int phonebook_get_name_by_number(u8 *number, u8 *name);
void bt_incall_time_update(void)
{
f_bt_call_t *f_bt_call = (f_bt_call_t *)func_cb.f_cb;
// char *call_time_str = f_bt_call->call_time_str;
// u16 call_times = f_bt_call->times;
// u8 f_bt_call->hours = call_times / 3600;
// u8 f_bt_call->minutes = (call_times % 3600) / 60;
// u8 f_bt_call->seconds = call_times % 60;
sprintf(f_bt_call->call_time_str, "%02d:%02d:%02d", phone_time.hour, phone_time.min, phone_time.sec);
// printf("call_time_str: %s\n", call_time_str);
compo_textbox_t *time_txt = compo_getobj_byid(COMPO_ID_TXT_TIME);
compo_textbox_set(time_txt, f_bt_call->call_time_str);
compo_textbox_set_visible(time_txt, true);
}
void func_bt_call_number_update(void)
{
int name_len = 0;
if (bt_cb.number_sta) {
compo_textbox_t *number_txt = compo_getobj_byid(COMPO_ID_TXT_NUMBER);
name_len = phonebook_get_name_by_number((u8*)hfp_get_last_call_number(0),(u8*)sys_cb.outgoing_name);
if(name_len > 0)
compo_textbox_set(number_txt, sys_cb.outgoing_name);
else
compo_textbox_set(number_txt, (const char*)hfp_get_last_call_number(0));
}
}
//创建窗体,创建窗体中不要使用功能结构体 func_cb.f_cb
compo_form_t *func_bt_call_form_create(void)
{
//printf("%s\n", __func__);
//新建窗体, 通话页面
compo_form_t *frm = compo_form_create(true);
//大背景
compo_picturebox_t *pic;
pic = compo_picturebox_create(frm, UI_BUF_CALL_CALL_BG_BIN);
compo_setid(pic, COMPO_ID_CALL_ICON);
compo_picturebox_set_pos(pic, GUI_SCREEN_CENTER_X, 2+37);
compo_textbox_t *number_txt = compo_textbox_create(frm, 20);
compo_textbox_set_location(number_txt, GUI_SCREEN_CENTER_X, 70+7 , GUI_SCREEN_WIDTH, 50);
compo_textbox_set_autosize(number_txt, true);
compo_setid(number_txt, COMPO_ID_TXT_NUMBER);
msg_enqueue(EVT_CALL_NUMBER_UPDATE);
compo_textbox_t *time_txt = compo_textbox_create(frm, 10);
compo_textbox_set_location(time_txt, GUI_SCREEN_CENTER_X, 93+5, GUI_SCREEN_WIDTH, 50);
compo_textbox_set_forecolor(time_txt,COLOR_GREEN);
compo_textbox_set_autosize(time_txt, true);
compo_setid(time_txt, COMPO_ID_TXT_TIME);
// 通话音量背景
compo_shape_t *vol_bar_bg = compo_radius_shape_create(frm, COMPO_SHAPE_TYPE_ROUNDED_RECTANGLE, 4);
compo_setid(vol_bar_bg, COMPO_ID_CALL_VOLUME_BG);
compo_shape_set_align_center(vol_bar_bg, false);
compo_shape_set_color(vol_bar_bg, make_color(38, 103, 65));
compo_shape_set_location(vol_bar_bg, 6, 37, 6, 80);
compo_shape_set_alpha(vol_bar_bg, 0);
compo_shape_set_visible(vol_bar_bg, false);
// 通话音量进度条
int height = SysVariable.hfp_vol * 80 / (VOL_MAX - 1);
compo_shape_t *vol_bar = compo_radius_shape_create(frm, COMPO_SHAPE_TYPE_ROUNDED_RECTANGLE, 4);
compo_setid(vol_bar, COMPO_ID_CALL_VOLUME);
compo_shape_set_align_center(vol_bar, false);
compo_shape_set_color(vol_bar, make_color(12, 227, 103));
compo_shape_set_location(vol_bar, 6, 37 + (80 - height), 6, height);
compo_shape_set_alpha(vol_bar, 0);
compo_shape_set_visible(vol_bar, false);
//挂断按钮
compo_button_t *btn;
btn = compo_button_create_by_image(frm, UI_BUF_CALL_HANG_UP_BIN);
compo_setid(btn, COMPO_ID_BTN_REJECT);
compo_button_set_pos(btn, GUI_SCREEN_CENTER_X, 117+16);
//mic
// btn = compo_button_create_by_image(frm, UI_BUF_CALL_MUTE_BIN);
// compo_setid(btn, COMPO_ID_BTN_MIC);
// compo_button_set_pos(btn, 49, 234);
return frm;
}
//创建窗体,创建窗体中不要使用功能结构体 func_cb.f_cb
compo_form_t *func_bt_outgoing_form_create(void)
{
//新建窗体, 呼出页面
compo_form_t *frm = compo_form_create(true);
compo_button_t *btn;
//大背景
compo_picturebox_t *pic;
pic = compo_picturebox_create(frm, UI_BUF_CALL_CALL_BG_BIN);
compo_setid(pic, COMPO_ID_CALL_ICON);
compo_picturebox_set_pos(pic, GUI_SCREEN_CENTER_X, 7+32);
compo_textbox_t *number_txt = compo_textbox_create(frm, 20);
compo_textbox_set_location(number_txt, GUI_SCREEN_CENTER_X, GUI_SCREEN_CENTER_Y, GUI_SCREEN_WIDTH, 50);
compo_textbox_set_autosize(number_txt, true);
compo_setid(number_txt, COMPO_ID_TXT_NUMBER);
msg_enqueue(EVT_CALL_NUMBER_UPDATE);
// 通话音量背景
compo_shape_t *vol_bar_bg = compo_radius_shape_create(frm, COMPO_SHAPE_TYPE_ROUNDED_RECTANGLE, 4);
compo_setid(vol_bar_bg, COMPO_ID_CALL_VOLUME_BG);
compo_shape_set_align_center(vol_bar_bg, false);
compo_shape_set_color(vol_bar_bg, make_color(38, 103, 65));
compo_shape_set_location(vol_bar_bg, 6, 37, 6, 80);
compo_shape_set_alpha(vol_bar_bg, 0);
compo_shape_set_visible(vol_bar_bg, false);
// 通话音量进度条
int height = SysVariable.hfp_vol * 80 / (VOL_MAX - 1);
compo_shape_t *vol_bar = compo_radius_shape_create(frm, COMPO_SHAPE_TYPE_ROUNDED_RECTANGLE, 4);
compo_setid(vol_bar, COMPO_ID_CALL_VOLUME);
compo_shape_set_align_center(vol_bar, false);
compo_shape_set_color(vol_bar, make_color(12, 227, 103));
compo_shape_set_location(vol_bar, 6, 37 + (80 - height), 6, height);
compo_shape_set_alpha(vol_bar, 0);
compo_shape_set_visible(vol_bar, false);
//挂断按钮
btn = compo_button_create_by_image(frm, UI_BUF_CALL_HANG_UP_BIN);
compo_setid(btn, COMPO_ID_BTN_REJECT);
compo_button_set_pos(btn, GUI_SCREEN_CENTER_X, 117+16);
return frm;
}
AT(.text.func.bt)
static void func_bt_call_interface(void)
{
f_bt_call_t *f_bt_call = (f_bt_call_t *)func_cb.f_cb;
if (bt_cb.disp_status == BT_STA_INCALL && f_bt_call->sta == false) {
//销毁窗体
if (func_cb.frm_main != NULL) {
compo_form_destroy(func_cb.frm_main);
}
func_cb.frm_main = func_bt_call_form_create();
f_bt_call->sta = true;
}
if (f_bt_call->sco_tick && tick_check_expire(f_bt_call->sco_tick, 1000)) {
f_bt_call->sco_tick = 0;
bt_hfp_switch_to_watch(); //通话音频强制切到手表
}
}
AT(.text.func.bt)
static void func_bt_call_exit_process(void)
{
f_bt_call_t *f_bt_call = (f_bt_call_t *)func_cb.f_cb;
if (!bt_cb.number_sta) { //号码未通知, 主动查询
if (tick_check_expire(f_bt_call->clcc_tick, 500)) {
f_bt_call->clcc_tick = tick_get();
bt_call_get_remote_phone_number();
}
}
if(bt_cb.disp_status != BT_STA_OUTGOING && bt_cb.disp_status != BT_STA_INCALL) { //退出通话页面
printf("func_bt_call_exit_process1111\n");
func_switch_to_assign_screen(FUNC_BT_END, false);
}
if (f_bt_call->exit_tick && tick_check_expire(f_bt_call->exit_tick, 1000)) { //强制退出, 防呆
f_bt_call->exit_tick = 0;
printf("func_bt_call_exit_process2222\n");
func_switch_to_assign_screen(FUNC_BT_END, false);
}
}
static void func_bt_call_animation_process(void)
{
f_bt_call_t *f_bt_call = (f_bt_call_t *)func_cb.f_cb;
compo_picturebox_t *pic = compo_getobj_byid(COMPO_ID_CALL_ICON);
if (f_bt_call == NULL || pic == NULL)
return;
u8 angle_per = 0;
s16 icon_size = 0;
if (tick_check_expire(f_bt_call->anim_tick, ANIMATION_TICK_EXPIRE))
{
f_bt_call->anim_tick = tick_get();
/* Calculated rotation Angle */
f_bt_call->anim_angle = (f_bt_call->anim_angle + ANIMATION_ROTATION_ANGLE) % 3600;
/* Gets the ICON size based on the rotation Angle */
if (f_bt_call->anim_angle < 3600 / 2) // lessen
{
angle_per = (f_bt_call->anim_angle * 100) / 1800;
icon_size = ((ANIMATION_ICON_SIZE_MAX - ANIMATION_ICON_SIZE_MIN) * angle_per) / 100;
icon_size = (ANIMATION_ICON_SIZE_MAX - ANIMATION_ICON_SIZE_MIN) - icon_size;
}
else // magnify
{
angle_per = ((f_bt_call->anim_angle - 1800) * 100) / 1800;
icon_size = ((ANIMATION_ICON_SIZE_MAX - ANIMATION_ICON_SIZE_MIN) * angle_per) / 100;
}
icon_size += ANIMATION_ICON_SIZE_MIN;
compo_picturebox_set_size(pic, icon_size, icon_size);
compo_picturebox_set_rotation(pic, f_bt_call->anim_angle);
}
}
static void func_bt_call_volume_bar_process(void)
{
f_bt_call_t *f_bt_call = (f_bt_call_t *)func_cb.f_cb;
compo_shape_t *vol_bar = compo_getobj_byid(COMPO_ID_CALL_VOLUME);
compo_shape_t *vol_bar_bg = compo_getobj_byid(COMPO_ID_CALL_VOLUME_BG);
if (f_bt_call == NULL || vol_bar == NULL || vol_bar_bg == NULL)
return;
if (f_bt_call->vol_hfp != SysVariable.hfp_vol)
{
int height = SysVariable.hfp_vol * 80 / (VOL_MAX - 1);
compo_shape_set_location(vol_bar, 6, 37 + (80 - height), 6, height);
compo_shape_set_visible(vol_bar, true);
compo_shape_set_visible(vol_bar_bg, true);
if(!f_bt_call->vol_show) {
f_bt_call->vol_alpha = !f_bt_call->vol_gradually ? 0 : f_bt_call->vol_alpha;
f_bt_call->vol_gradually = 1;
f_bt_call->vol_show = true;
}
f_bt_call->amin_tick = tick_get();
f_bt_call->vol_show_tick = tick_get();
f_bt_call->vol_hfp = SysVariable.hfp_vol;
}
/* 超时退出 */
if (tick_check_expire(f_bt_call->vol_show_tick, VOLUME_BAR_TIME_MAX) && f_bt_call->vol_show) {
f_bt_call->vol_show = false;
f_bt_call->vol_alpha = 255;
f_bt_call->vol_gradually = 2;
f_bt_call->amin_tick = tick_get();
}
/* 淡入淡出 */
if (tick_check_expire(f_bt_call->amin_tick, VOLUME_BAR_ANIM_TIME_MAX) && f_bt_call->vol_gradually) {
f_bt_call->amin_tick = tick_get();
if (f_bt_call->vol_gradually == 1) {
if (f_bt_call->vol_alpha < 255)
f_bt_call->vol_alpha += 5;
if (f_bt_call->vol_alpha >= 255) {
f_bt_call->vol_alpha = 255;
f_bt_call->vol_gradually = 0;
}
}
else
{
if (f_bt_call->vol_alpha > 0)
f_bt_call->vol_alpha -= 5;
if (f_bt_call->vol_alpha <= 0) {
f_bt_call->vol_alpha = 0;
f_bt_call->vol_gradually = 0;
compo_shape_set_visible(vol_bar, false);
compo_shape_set_visible(vol_bar_bg, false);
}
}
compo_shape_set_alpha(vol_bar, f_bt_call->vol_alpha);
compo_shape_set_alpha(vol_bar_bg, f_bt_call->vol_alpha);
}
}
void func_bt_call_process(void)
{
func_process();
func_bt_sub_process();
func_bt_call_exit_process();
func_bt_call_interface();
/* Call ICON animation */
func_bt_call_animation_process();
/* Display volume bar when volume changes */
func_bt_call_volume_bar_process();
}
static void func_bt_call_click(void)
{
f_bt_call_t *f_bt_call = (f_bt_call_t *)func_cb.f_cb;
int id = compo_get_button_id();
switch (id) {
case COMPO_ID_BTN_REJECT:
printf("COMPO_ID_BTN_REJECT\n");
bt_call_terminate();
f_bt_call->exit_tick = tick_get();
break;
default:
break;
}
}
//蓝牙音乐消息处理
static void func_bt_call_message(size_msg_t msg)
{
f_bt_call_t *f_bt_call = (f_bt_call_t *)func_cb.f_cb;
switch (msg) {
/* UX不响应处理触摸滑动事件 */
case MSG_CTP_TOUCH:
case MSG_CTP_SHORT_RIGHT:
break;
/* 单击静音 */
case KU_BACK:
bt_volume_set(0);
f_bt_call->vol_hfp = 0xff;
break;
/* 双击挂断 */
case KD_BACK:
bt_call_terminate();
f_bt_call->exit_tick = tick_get();
break;
case KU_RIGHT:
if(bt_get_call_indicate() == BT_CALL_INCOMING) {
bt_call_answer_incoming(); //接听第2路通话
} else {
bt_call_terminate(); //挂断当前通话
sys_cb.motor_flag = 1;
set_func_motor(80,2,2,1);
}
break;
case KU_LEFT:
break;
case MSG_SYS_1S:
if (f_bt_call->sta == true) {
// f_bt_call->times++;
bt_incall_time_update();
}
break;
case MSG_CTP_CLICK:
func_bt_call_click(); //单击按钮
break;
case EVT_CALL_NUMBER_UPDATE:
if (bt_get_call_indicate() == BT_CALL_ACTIVE || bt_get_call_indicate() == BT_CALL_3WAY_CALL|| bt_get_call_indicate() == BT_CALL_OUTGOING) {
func_bt_call_number_update();
}
break;
case MSG_SYS_500MS:
if(bt_cb.disp_status == BT_STA_OUTGOING)
{
reset_sleep_delay_all(); // 来电不休眠
}
break;
default:
func_message(msg);
break;
}
}
void func_bt_call_enter(void)
{
func_cb.f_cb = func_zalloc(sizeof(f_bt_call_t));
f_bt_call_t *f_bt_call = (f_bt_call_t *)func_cb.f_cb;
func_cb.frm_main = func_bt_outgoing_form_create();
func_cb.mp3_res_play = func_bt_mp3_res_play;
bsp_bt_call_enter();
if (sys_cb.gui_sleep_sta) {
sys_cb.gui_need_wakeup = 1;
}
f_bt_call->vol_hfp = SysVariable.hfp_vol;
}
void func_bt_call_exit(void)
{
bsp_bt_call_exit();
bsp_motor_stop(MOTOR_PORT);
}
void func_bt_call(void)
{
printf("%s\n", __func__);
u16 interval = 0, latency = 0, tout = 0;
// Adjust BLE connection parameter when incall
if (ble_is_connect() && (ble_get_conn_interval() < 400)) {
interval = ble_get_conn_interval();
latency = ble_get_conn_latency();
tout = ble_get_conn_timeout();
ble_update_conn_param(480, 0, 500);
}
func_bt_call_enter();
while (func_cb.sta == FUNC_BT_CALL) {
func_bt_call_process();
func_bt_call_message(msg_dequeue());
}
func_bt_call_exit();
// Restore BLE connection parameter
if (interval | latency | tout) {
ble_update_conn_param(interval, latency, tout);
}
}