杰理芯片SDK-详细讲解AC695N/AC696N芯片SDK中APP模式流程

前言

现在为止也开发了许多杰理TWS蓝牙耳机、音响项目SDK的案子,在调试案子时不断的向前辈们学习到了很多关于蓝牙音响、蓝牙TWS耳机专业的知识。想在这里做一个学习汇总,方便各位同行和对杰理芯片SDK感兴趣的小伙伴们学习;

本章详细介绍杰理AC695N/AC696N芯片SDK中APP模式流程

在我们开发蓝牙产品时有产品可能有许多模式,这时候就需要一个模式配置管理,本章详细介绍AC695N/AC696N芯片SDK中APP模式流程;

APP模式设置

上电设置app模式,在app_main.c文件中app_main()函数中设置开机默认模式任务有APP_POWERON_TASK模式如图所示:


PWERON开机模式进入

依靠应用任务主循环(任务调度器)app_task_loop()函数进入app_poweron_tassk() 开机模式任务,如图所示:


APP模式切换

(1)进入app_poweron_task()函数中

(2)进入tone_play_end_callback(void *priv, int flag)函数中,如图所示:

(3)进入power_on_init(void)函数中设置下一模式值

可以看到开机后,会进入蓝牙模式;如果想开机后进入某种模式在此函数中进行设置就好;如图所示,如果音乐模式使能后。会检测是否有设备(U盘/TF卡插入),插入会直接进入音乐模式;

(4)发送APP_MSG_SWITCH_TASK切换消息

(5)power模式退出。跳出while(1)循环


APP模式配置表和APP模式管理函数

APP模式配置表和APP模式管理函数集中在" app_task_switch.c "文件中

(1)APP模式配置表,在这里可以配置切换模式的顺序,方案根据需求定义;

(2)APP模式管理函数

cpp 复制代码
//*----------------------------------------------------------------------------*/
/**@brief    模式退出检查
   @param    curr_task:当前模式
   @return   TRUE可以退出, FALSE不可以退出
   @note
*/
/*----------------------------------------------------------------------------*/
static int app_task_switch_exit_check(u8 curr_task)
{
    int ret = false;
    switch (curr_task) {
    case APP_BT_TASK:
        ret = bt_app_exit_check();
        break;
    default:
        ret = TRUE;
        break;

    }
    return ret;
}
//*----------------------------------------------------------------------------*/
/**@brief    模式进入检查
   @param    app_task:目标模式
   @return   TRUE可以进入, FALSE不可以进入
   @note	 例如一些需要设备在线的任务(music/record/linein等),
   			 如果设备在线可以进入, 没有设备在线不进入可以在这里处理
*/
/*----------------------------------------------------------------------------*/
static int app_task_switch_check(u8 app_task)
{
    int ret = false;
    switch (app_task) {
#if TCFG_APP_MUSIC_EN
    case APP_MUSIC_TASK:
        ret = music_app_check();
        break;
#endif
#if TCFG_APP_LINEIN_EN
    case APP_LINEIN_TASK:
        ret = linein_app_check();
        break;
#endif
#if TCFG_APP_PC_EN
    case APP_PC_TASK:
        ret = pc_app_check();
        break;
#endif
    case APP_FM_TASK:
        ret = TRUE;
        break;
#if TCFG_APP_RECORD_EN
    case APP_RECORD_TASK:
        ret = record_app_check();
        break;
#endif
    default:
        ret = TRUE;
        break;

    }
    return ret;
}
//*----------------------------------------------------------------------------*/
/**@brief    切换到上一个模式
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
void app_task_switch_prev()
{
    int i = 0;
    int cur_index = 0;

    if (app_next_task) {
        printf("app_task_switch_prev busy \n");
    }

    for (cur_index = 0; cur_index < ARRAY_SIZE(app_task_list); cur_index++) {
        if (app_curr_task == app_task_list[cur_index]) {//遍历当前索引
            break;
        }
    }

    for (i = cur_index; ;) { //遍历一圈
        if (i-- == 0) {
            i = ARRAY_SIZE(app_task_list) - 1;
        }
        if (i == cur_index) {
            return;
        }
        if (app_task_switch_to(app_task_list[i])) {
            return;
        }
    }
}
//*----------------------------------------------------------------------------*/
/**@brief    切换到下一个模式
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
void app_task_switch_next()
{
    int i = 0;
    int cur_index = 0;

    if (app_next_task) {
        printf("app_task_switch_next busy \n");
    }

    for (cur_index = 0; cur_index < ARRAY_SIZE(app_task_list); cur_index++) {
        if (app_curr_task == app_task_list[cur_index]) {//遍历当前索引
            break;
        }
    }

    for (i = cur_index ;;) { //遍历一圈
        if (++i >= ARRAY_SIZE(app_task_list)) {
            i = 0;
        }
        if (i == cur_index) {
            return;
        }
        if (app_task_switch_to(app_task_list[i])) {
            return;
        }
    }
}
//*----------------------------------------------------------------------------*/
/**@brief    切换到指定模式
   @param    app_task:指定模式
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
int app_task_switch_to(u8 app_task)
{
    if (app_curr_task == app_task) {
        return false;
    }

    if (!app_task_switch_check(app_task)) {
        return false;
    }

    if (!app_task_switch_exit_check(app_curr_task)) {
        return false;
    }

    printf("cur --- %x \n", app_curr_task);
    printf("new +++ %x \n", app_task);

    /* if(app_next_task) */
    /* printf("app_task_switch_to busy \n"); */
#if (defined SMART_BOX_EN) && (SMART_BOX_EN)
    extern void function_change_inform(u8 app_mode, u8 ret);
    function_change_inform(app_task, TRUE);
#endif

#if (RECORDER_MIX_EN)
    recorder_mix_stop();
#endif/*RECORDER_MIX_EN*/

    // 这是状态机的核心变量,app_task_loop 将根据这两个变量执行切换。

    app_prev_task = app_curr_task;              //记录从那个模式来
    app_next_task = app_task;                   //记录要求那个模式
    app_task_put_usr_msg(APP_MSG_SWITCH_TASK, 0);   //发送切换模式消息

    return TRUE;
}

//*----------------------------------------------------------------------------*/
/**@brief    跳回到原来的模式
   @param
   @return
   @note
*/
/*----------------------------------------------------------------------------*/
int app_task_switch_back()
{
    if (app_prev_task == 0) {
        return -EINVAL;
    }
    return app_task_switch_to(app_prev_task);
}

//*----------------------------------------------------------------------------*/
/**@brief    模式切换退出检测
   @param
   @return   1:响应退出模式, 0:不响应
   @note
*/
/*----------------------------------------------------------------------------*/
u8 app_task_exitting()//
{
    struct sys_event clear_key_event = {.type =  SYS_KEY_EVENT, .arg = (void *)DEVICE_EVENT_FROM_KEY};
    if (app_next_task != 0) {
        app_curr_task = app_next_task;
        app_next_task = 0;
        sys_key_event_disable();
        sys_event_clear(&clear_key_event);
        return 1;
    }
    return 0;
}

//*----------------------------------------------------------------------------*/
/**@brief    获取当前模式
   @param
   @return   当前模式id
   @note
*/
/*----------------------------------------------------------------------------*/
u8 app_get_curr_task()
{
    return app_curr_task;
}

//*----------------------------------------------------------------------------*/
/**@brief    通过指定id检查是否是当前模式
   @param
   @return   true:是当前模式,false:不是当前模式
   @note
*/
/*----------------------------------------------------------------------------*/
u8 app_check_curr_task(u8 app)
{
    if (app == app_curr_task) {
        return true;
    }
    return false;
}

制作不易!喜欢的小伙伴给个小赞赞!喜欢我的小伙伴点个关注!有不懂的地方和需要的资源随时问我哟!

相关推荐
voipmaker3 小时前
GB28181 对接踩坑实录:注册不上、目录不全、流卡顿,一次说清(附 2022 版变更清单)
物联网·音视频·实时音视频·信息与通信·iot·gb28181·国标gb28181
吠品3 小时前
智谱开源 ZCode 之后,真正的考试才开始
单片机·嵌入式硬件·1024程序员节
Chery11405 小时前
高速ADC与精密DAC怎么选?DP9230D与DP8532D应用解析
嵌入式硬件·物联网·射频工程
小李不想当小白8 小时前
SPI通信外设与W25Q64 (硬件SPI)(STM32标准库学习笔记)
笔记·stm32·单片机·嵌入式硬件·学习·嵌入式
LCG米8 小时前
STM32驱动W5500以太网模块实测:TCP吞吐瓶颈定位、TX指针回绕陷阱与断线重连保活落地
stm32·单片机·嵌入式硬件·tcp/ip
尼喃9 小时前
662K/65Z5三脚稳压芯片规格书—PW6566B33/B30引脚功能
嵌入式硬件
创界工坊工作室9 小时前
63-基于STC89C52霍尔传感器的智能化电能表设计
stm32·单片机·嵌入式硬件·51单片机·proteus
智购科技自动售货机厂家11 小时前
让AI经营自动售货机:从Project Vend看工具权限与业务规则~YH
大数据·服务器·单片机·嵌入式硬件·深度学习
Zwawa12 小时前
从 printf 到曲线:把数据送上 VOFA+
c语言·单片机·嵌入式
意法半导体STM3212 小时前
【官方原创】LAT6048 如何扩大MP2的A35核和M33核共享内存
stm32·单片机·嵌入式硬件·内存映射·stm32mp2