KDocs 研发资料库
  • 音频技术应用文档入口汇总
  • 杰理WINDOWS环境安装及其他事项
  • LINUX安装和编译
  • Linux环境编译SDK教程(ubuntu18.04)
  • 音频类补丁汇总表
  • 认证资料获取汇总(最新资料后台会更新)
  • 《Hi-Res申请指南v1.0》
  • FreeRTOS 开源协议版本
  • uCOS 开源协议版本信息
  • 各个模块关键资料汇总
  • 软件调试方法
  • Makefile编译
  • 提bug的规范
  • 常规设备使用指导
  • 对外特别发布开发注意点信息汇总
  • AD697X软件问题整理
  • AC700N软件问题整理
  • AC701X耳机软件问题整理
  • 951&961软件问题整理
  • AC104X软件问题整理
  • AC128N问题整理文档
  • 可视化工具调试问题整理
  • 耳机资料汇总
  • AC704N、 AC705N相关应用
  • AC695N&AC696N&AC608N音箱问题整理
  • JL701N音箱问题整理
  • AC692X软件问题整理
  • AC706N音箱问题整理
  • JL701N音箱问题整理(可视化工具SDK)
  • JL703N音箱问题整理
  • JL709N(JL689N)音箱问题整理
  • JL7094系列-入门到进阶开发指导
  • AC210N音箱问题整理
  • 无线麦系列版本支持指南
  • AW32N无线麦问题整理
  • lAD697X&JL701X 无线麦软件共性问题整理
  • AC706N无线麦问题整理
  • AW36N无线麦问题整理
  • AC710X无线麦问题整理
  • 唤醒源获取及唤醒IO设置
  • 电源
  • LVD
  • 长按复位配置方法
  • 低功耗应用
  • TIMER
  • UART
  • SPI
  • 内部FLASH空间添加用户自定义区域
  • IIC
  • GPIO
  • MCPWM
  • SD&U盘
  • 时钟&晶振
  • GPCNT
  • IO口crossbar映射功能
  • 文件系统使用总结
  • 复用应用
  • LINEIN_AUX相关应用
  • IIS音频接口应用
  • SPDIF模式相关(HDMI_ARC、光纤、同轴)
  • PDM LINK
  • 外设相关应用
  • 蓝牙相关
  • 杰理蓝牙距离调试文档
  • TWS耳机配对方式使用及生产把控指南
  • GFP谷歌快连及其认证流程指引
  • 蓝牙发射器(bt_emitter)相关
  • BLE应用
  • 关于提升BLE传输速率说明
  • BLE测试数据
  • MUSIC 模式相关应用
  • MIDI音乐实现
  • PC相关应用
  • FM相关应用
  • AC695N_AC696N FM天线ESD静电防护措施说明V2.0_20250107
  • fm应用详细设计说明书
  • 杰理FM硬件指南-20230315
  • ADC模块
  • AUDIO相关应用
  • 新Tools的音效调试使用
  • 混响应用使用说明
  • 音效调式
  • 音箱耳机低音小音量增强实现方法
  • DAC输出功率调试
  • DAC性能测试指南
  • 针对各类底噪、电流声分析流程
  • 录音相关应用
  • OPUS编解码相关
  • RTC相关应用
  • 升级相关
  • UI相关应用
  • 通话调试流程指南
  • 通话相关应用
  • 省电容mic使用手册
  • 如何测试验证手表通话系统的语音失真 V1.0
  • AC695X_AC696X_AD697X 常见通话问题处理参考资料
  • 通话调试问题确定步骤
  • 内置触摸调试指南
  • 低功耗内置触摸介绍V2.2
  • 触摸相关文档
  • AC697X、AC698X内置触摸调试及整改方法V1.0
  • 产测相关应用
  • AC63X BLE DUT测试介绍
  • 兆华序列使用简易说明
  • JL_1T2蓝牙测试盒音频文件更换说明
  • ENC相关应用入口汇总
  • ANC相关应用入口汇总
  • JL DMS通话调试手册-V3.9.4
  • ANC-ENC结构设计要点-20240407
  • 半入耳式ANC耳机器件选型与结构设计指南V1.0
  • JL 耳道自适应调试指南
  • ANC相关问题处理
  • ANC调试文档
  • 评估蓝牙耳机通话上行降噪性能的方法 V1.0 (2)
  • FCC 或者 BQB 认证相关应用
  • BQB profile 测试中常遇到的问题点汇总
  • 蓝牙参数整理20210811
  • 杰理科技认证问题参考
  • 无线音频产品开发指南
  • 无线麦系列从入门到进阶开发指导
  • 量产烧录相关说明
  • 一拖八烧录器远程过程调用说明
  • 量产相关建议
  • EffectTool(eq)调试工具说明文档
  • AC897AD697系列的EQ调试方法-V3
  • 杰理调音指南-20220622
  • 音效模块总结
  • 简要调音步骤指引(可视化)
  • 耳机充电与通信调试指南
  • 充电仓硬件调试指南
  • 充电仓软件问题整理
  • AC951常用说明
  • AC951_AC961_开发板使用说明V1.0
  • 彩屏仓AC982 入门指导及FAQ
  • 蓝牙音频APP相关应用
  • 手机APP的简介和开发流程
  • 蓝牙音频系列-硬件设计指南
  • 静电测试及整改方法-20220706
  • TWS耳机底噪整改指南V1.2
  • 杰理蓝牙距离调试文档
  • 蓝牙RF硬件设计与调试V1.1-20250219
  • AC695N_AC696N FM天线ESD静电防护措施说明V2.0_20241228
  • 音效调试指南
  • 无线话筒K歌音箱标准开发流程
  • 杰理科技 700N TWS耳机产品标准-202303
  • 杰理科技 701N 广播产品标准-202303
  • JL-HAT ANC高效产测自适应
  • 无线话筒测试板使用介绍
  • 一拖八频偏校准使用说明
  • 领夹麦产测工具使用介绍
  • Dongle量产测试说明
  • Dongle+Tws或头戴式 SDK通过工具绑定配对功能说明文档
  • 双麦ENC产测宏配置验证方法 V1.0
  • JL耳机方案麦克风声学测试指令_V1.0
  • JL耳机方案麦克风声学测试指令_V2.0
  • JL_ENC自动测试命令_V0.0.1
  • JL蓝牙测试盒用例说明
  • LDAC自测环境搭建_ubuntu
  • 延迟小板使用手册
  • 杰理库文件的制作及添加实现过程
  • 关于 AC635N&AC636N系列免晶振兼容性补丁 说明
  • 关于 AC63系列VM兼容性修复补丁_20250224 说明
  • 关于 AC632N &AE632N_ 蓝牙& 低功耗兼容性修复补丁 说明
  • AD698N和AC638N电压优化补丁V3说明
  • 关于 AC635N&AC636N漏电和E&G版兼容联合补丁 说明
  • AD698N和AC638N电压优化补丁V2说明
  • 702相关应用
  • 2024-4-30 发布歌词显示SDK开发注意事项
  • BQB RF & FCC 认证测试固件问题汇总及源码
  • BQB profile 测试中常遇到的问题点汇总
  • 进dut测试模式方法及固件
  • 704-频偏修改bin文件合集
  • 701手表BQB PROFILE认证注意事项
  • 认证的干扰规避整改
  • 海外CRA认证报告生成说明
  • JL700N可视化工具问题处理文档
  • JL701X可视化工具问题处理文档
  • JL701N_earphone_release_v1.6.0_ANC 低功耗问题补丁
  • JL708X可视化工具问题处理文档
  • JL709N可视化工具问题处理文档
  • JLstudio可视化工具使用说明
  • 一拖二-串口_蓝牙_app在线EQ、通话参数及调试方式和内置触摸调试
  • 可视化JL701M_DONGLE_SDK添加MIC为发射源
  • 可视化JL701M_DONGLE_SDK添加按键切换usb audio与MIC发射源
  • JL701M_DONGLE_SDK_1.0.0_dongle输入linein输出dac
  • 701可视化_a2dp_to_le_demo说明
  • 耳机系列demo汇总
  • JL7018F&JL7006F_7003F AUX IIS
  • 一键连接应用
  • 普通SDK动态开关一拖二功能
  • 蓝牙分析仪(EllisysBluetoothAnalyzer)抓包例程
  • TWS配对常见应用
  • APP自定义按键的demo
  • AC700N 播歌双EQ DEMO示例及说明
  • AC698V164 MIC与蓝牙音乐共同输出DAC demo
  • 添加第三方算法以及多算法授权流程
  • 空间音频配置方法
  • 普通高低电平TWS耳机控制通讯
  • 入耳检测状态更新demo解析
  • 资源优化(非可视化的SDK)
  • 资源优化(可视化SDK)
  • 翻译耳机、语音识别应用demo
  • 耳机抗干扰问题排查和优化
  • AC698D2 抗干扰优化
  • AC696X软件问题整理
  • AC695X软件问题整理
  • AC695X软件问题整理_1722249702
  • AC608X软件问题整理
  • JL701N_2T1_DUPLEX 应用软件问题汇总
  • le_audio_1.0.0_patch05 以及之前的版本IRkey 功能异常修改
  • AC706N-le_audio-200SDK有线_无线麦录音demo
  • jl701n_le_audio_v200patch02 IO串口升级修改串口单次发送字节长度的修改办法
  • 703创建IIS 输入dac输出音频流demo
  • 703将媒体流音频同时上传PC_mic录音demo实现
  • 703四路IIS输入输出demo
  • 底噪调试
  • AW328A烧录说明
  • 文档合集
  • AC706N_wireless_mic_release_PATCH_20240712 补丁 说明
  • AC706N_wireless_mic_release_PATCH_20240726 补丁 说明
  • AC706N_wireless_mic_release_V1.0.0、1.0.1、1.0.2 补丁 说明
  • AC706N_wireless_mic_release_V1.1.2 中的2T1应用 RX端不绑定配对,TX端实现绑定配对的修改方法
  • 各系列省晶振实现方法
  • iis tx rx说明文档
  • spdif信号
  • 蓝牙电话本
  • 安卓手机同步时间补丁
  • CDC配置
  • PC模式下增加Teams唤起功能
  • 杰理HDMIARC开发实现过程
  • AC701N patch06之前的版本用第三方算法节点实现新版本的pcm delay节点功能
  • (K歌音箱)各SDK音效配置相关说明
  • 长文件录音
  • 点阵屏歌词字库相关(蓝牙歌词,普通歌词)
  • 字模提取工具说明
  • 音箱可视化彩屏-入门到进阶开发指导
  • 彩屏LVGL UI设计及工具使用
  • 使用内部UI框架进行UI调试的系列步骤
  • AD101C使用强制升级工具spi 烧录不了问题处理(测试版本)
  • AD161扩展灯板说明文档
  • 歌词显示器开发注意项
  • 使用硬件数字增益控制通话下行音量(可视化)
  • 杰理小牛产测资料
  • ENC配置说明
  • 通话调试流程指引
  • ANC相关功能demo
  • 无线麦硬件资料汇总
  • 无线麦相关应用
  • 无线麦复杂功能补丁包汇总
  • 无线话筒形态SDK程序&开发经验&问题点分享
  • 双模式结合应用问题汇总
  • 无线麦距离优化案例
  • 无线麦系列中的双工形态(duplex)演变开发对讲机方案开发资料
  • 音箱入门到进阶指导文档(编写中)
  • 蓝牙耳机品控和生产技巧
  • 982过_欠压标志获取异常
  • 如何获取最新涂鸦SDK及库文件
  • 无线话筒K歌音响-调音标准流程
  • 无线话筒产测流程

APP自定义按键的demo

📎 原始文档:https://www.kdocs.cn/l/ccQQJb6UcJUv APP自定义按键的demo

demo代码

【金山文档】 app_define_key (普通SDK)
https://kdocs.cn/l/cvG7yfD5uZpA
【金山文档】 app_define_key_1t2(可视化SDK)
https://kdocs.cn/l/ccJmcq29RE9i
使用方法详见以上demo内的注释

支持的功能:

  1. 支持多种场景下的按键自定义 例如通话场景、播歌场景,通过APP_KEY_SENCE枚举定义场景,在key_2_func函数中识别当前场景。
/**
 * @brief APP定义的按键场景,根据APP定义修改
 * 
 */
typedef enum {
    KEY_SENCE_CALL_IN, //来电场景
    KEY_SENCE_HANGUP,  //非通话场景
    KEY_SENCE_ALL,     //任何场景
    KEY_SENCE_CALLING, //通话中场景
    KEY_SENCE_MAX,
}APP_KEY_SENCE;

static u8 key_2_func(APP_KEY_CHANNEL channel, APP_KEY_BUTTON button, APP_KEY_ACTION action)
{
    APP_KEY_SENCE sence = KEY_SENCE_MAX;
    switch (get_call_status()) //这个switch要根据项目APP的场景改,完成耳机状态到APP场景的转换
    {
    case BT_CALL_HANGUP:
        sence = KEY_SENCE_HANGUP;//非通话场景
        break;
    case BT_CALL_ACTIVE:
        // sence = KEY_SENCE_CALLING;
        // break;
    case BT_CALL_INCOMING:
        sence = KEY_SENCE_CALL_IN;//通话场景
        break;

    default:
        break;
    }
    //......下面的代码省略,具体看demo
}
  1. 支持添加多种按键动作 通过APP_KEY_ACTION枚举定义按键动作,在app_key_deal函数中识别当前按键动作
/**
 * @brief APP定义的按键动作,根据APP定义修改
 * 
 */
typedef enum {
    KEY_ACTION_1_CLICK, //单击
    KEY_ACTION_2_CLICK, //双击
    KEY_ACTION_LONG,    //长按
    KEY_ACTION_3_CLICK, //三击
    KEY_ACTION_MAX,
}APP_KEY_ACTION;

//app过来的按键事件跟耳机本地的按键事件值可能不一样,用这个数组转换一下
const APP_KEY_ACTION local_action_to_ext_action[KEY_EVENT_MAX] = {
    [KEY_EVENT_CLICK] = KEY_ACTION_1_CLICK,
    [KEY_EVENT_DOUBLE_CLICK] = KEY_ACTION_2_CLICK,
    [KEY_EVENT_TRIPLE_CLICK] = KEY_ACTION_3_CLICK,
};

u8 app_key_deal(u8 from_tws, u8 key_value, u8 key_status)
{
    //......上面的代码省略,具体看demo
    case KEY_EVENT_DOUBLE_CLICK:
    case KEY_EVENT_TRIPLE_CLICK:
        key_action = local_action_to_ext_action[key_status];
    //......中间的代码省略,具体看demo
    case KEY_EVENT_LONG:
        key_action = KEY_ACTION_LONG;
    //......下面的代码省略,具体看demo
}
  1. 支持添加多个按键值 通过APP_KEY_BUTTON枚举定义按键值,在app_key_deal函数中识别当前按键值
/**
 * @brief APP定义的按键值,根据APP定义修改
 * 
 */
typedef enum {
    KEY_BUTTON_1,
    // KEY_BUTTON_2,
    // KEY_BUTTON_3,
    // KEY_BUTTON_4,
    KEY_BUTTON_MAX,
}APP_KEY_BUTTON;

u8 app_key_deal(u8 from_tws, u8 key_value, u8 key_status)
{
    //......上面的代码省略,具体看demo
    APP_KEY_BUTTON button = key_value;//本地按键值转APP按键值(根据APP修改,APP没有按键值定义的可以不改)
    //......下面的代码省略,具体看demo
}
  1. 支持添加多种操作类型 比如左边操作按键、右边操作按键、左右同时操作按键等,通过APP_KEY_CHANNEL枚举定义操作类型,在app_key_deal函数中识别当前操作类型
/**
 * @brief APP定义的按键按下类别,根据APP定义修改
 * 
 */
typedef enum {
    KEY_CHANNEL_L, //左耳按下
    KEY_CHANNEL_R, //右耳按下
    KEY_CHANNEL_MAX,//把MAX放在这里,表示下面的功能关闭,要打开或者新增功能,要放在MAX上面
    KEY_CHANNEL_B, //盒子按下,此项目不用
    KEY_CHANNEL_LR, //左右耳一起按下,此项目不用
}APP_KEY_CHANNEL;

u8 app_key_deal(u8 from_tws, u8 key_value, u8 key_status)
{
    u8 channel = KEY_CHANNEL_LR;
    //......上面的代码省略,具体看demo
        if (get_bt_tws_connect_status()) {
            channel = tws_api_get_local_channel();
            if ('L' == channel) {
                channel = from_tws ? KEY_CHANNEL_R : KEY_CHANNEL_L;
            } else {
                channel = from_tws ? KEY_CHANNEL_L : KEY_CHANNEL_R;
            }
        }
        else{
            channel = tws_api_get_local_channel() == 'L' ? KEY_CHANNEL_L : KEY_CHANNEL_R;
        }
    //......下面的代码省略,具体看demo
}
  1. 支持添加自定义按键功能 在Function枚举中定义APP端的按键功能,在app_key_func_deal函数中实现功能
/**
 * @brief APP定义的按键功能,根据APP定义修改
 * 
 */
typedef enum {
    CANCLE_OPTION,              //关闭操作
    CALL_ANSWER,                //接听电话
    CALL_REJECT_HANGUP,         //拒接或挂断电话
    MUSIC_PP,                   //暂停播放
    MUSIC_PREV,                 //上一曲
    MUSIC_NEXT,                 //下一曲
    START_SIRI,                 //唤醒语音助手
    SWITCH_ANC,                 //降噪模式切换
    VOLUME_UP,                  //增大音量
    VOLUME_DOWN,                //减小音量
    CALL_ANSWER_HANGUP,         //接听或挂断电话
    CALL_REJECT,                //拒接电话
    CALL_HANGUP,                //挂断电话
    GAME_MODE,                  //游戏模式
/******************以下暂时不用*********************/
    RANDOM_MUSIC,               //随心听歌
    START_GOOGLE,               //Google语音助手
    SET_VOLUME,                 //调节音量
    PLAY_COLLECTION,            //播放收藏歌曲
    PREV_OR_NEXT,               //上一曲/下一曲
    FORCE_CONN,                 //抢连
    SECOND_CALL_HOLD_ON,        //保持三方通话
}Function;
  1. 支持设置默认按键功能 首次开机,没有连接APP修改按键时,使用默认的按键功能,通过以下数组设定默认的按键功能,通过app_key_reset函数重置按键功能到默认。
    不需要默认功能时,将对应操作下的功能改为CANCLE_OPTION。
//对应默认的功能UI,第一次开机或者恢复出厂设置时使用
const u8 default_key_info_call_in[KEY_CHANNEL_MAX * KEY_ACTION_MAX][4] = {  //对应来电场景的默认按键功能
    {KEY_CHANNEL_L, KEY_BUTTON_1, KEY_ACTION_1_CLICK, (VOLUME_DOWN)},       //左耳按键单击音量减
    {KEY_CHANNEL_R, KEY_BUTTON_1, KEY_ACTION_1_CLICK, (VOLUME_UP)},         //右耳按键单击音量加
    {KEY_CHANNEL_L, KEY_BUTTON_1, KEY_ACTION_2_CLICK, (CALL_ANSWER_HANGUP)},//左耳按键双击接挂电话
    {KEY_CHANNEL_R, KEY_BUTTON_1, KEY_ACTION_2_CLICK, (CALL_ANSWER_HANGUP)},//右耳按键双击接挂电话
    {KEY_CHANNEL_L, KEY_BUTTON_1, KEY_ACTION_3_CLICK, (CANCLE_OPTION)},     //左耳按键三击无功能
    {KEY_CHANNEL_R, KEY_BUTTON_1, KEY_ACTION_3_CLICK, (CANCLE_OPTION)},     //右耳按键三击无功能
    {KEY_CHANNEL_L, KEY_BUTTON_1, KEY_ACTION_LONG, (CALL_REJECT)},          //左耳按键长按拒接
    {KEY_CHANNEL_R, KEY_BUTTON_1, KEY_ACTION_LONG, (CALL_REJECT)},          //右耳按键长按拒接
    // {KEY_CHANNEL_LR, KEY_BUTTON_1, KEY_ACTION_LONG, (GAME_MODE)},
};

const u8 default_key_info_hangup[KEY_CHANNEL_MAX * KEY_ACTION_MAX][4] = {   //对应非通话场景的默认按键功能
    {KEY_CHANNEL_L, KEY_BUTTON_1, KEY_ACTION_1_CLICK, (VOLUME_DOWN)},
    {KEY_CHANNEL_R, KEY_BUTTON_1, KEY_ACTION_1_CLICK, (VOLUME_UP)},
    {KEY_CHANNEL_L, KEY_BUTTON_1, KEY_ACTION_2_CLICK, (MUSIC_PP)},
    {KEY_CHANNEL_R, KEY_BUTTON_1, KEY_ACTION_2_CLICK, (MUSIC_PP)},
    {KEY_CHANNEL_L, KEY_BUTTON_1, KEY_ACTION_3_CLICK, (GAME_MODE)},
    {KEY_CHANNEL_R, KEY_BUTTON_1, KEY_ACTION_3_CLICK, (START_SIRI)},
    {KEY_CHANNEL_L, KEY_BUTTON_1, KEY_ACTION_LONG, (MUSIC_PREV)},
    {KEY_CHANNEL_R, KEY_BUTTON_1, KEY_ACTION_LONG, (MUSIC_NEXT)},
    // {KEY_CHANNEL_LR, KEY_BUTTON_1, KEY_ACTION_LONG, (GAME_MODE)},
};

const u8 default_key_info_all[KEY_CHANNEL_MAX * KEY_ACTION_MAX][4] = {      //对应任何场景的默认按键功能
    {KEY_CHANNEL_L, KEY_BUTTON_1, KEY_ACTION_1_CLICK, (CANCLE_OPTION)},
    {KEY_CHANNEL_R, KEY_BUTTON_1, KEY_ACTION_1_CLICK, (CANCLE_OPTION)},
    {KEY_CHANNEL_L, KEY_BUTTON_1, KEY_ACTION_2_CLICK, (CANCLE_OPTION)},
    {KEY_CHANNEL_R, KEY_BUTTON_1, KEY_ACTION_2_CLICK, (CANCLE_OPTION)},
    {KEY_CHANNEL_L, KEY_BUTTON_1, KEY_ACTION_3_CLICK, (CANCLE_OPTION)},
    {KEY_CHANNEL_R, KEY_BUTTON_1, KEY_ACTION_3_CLICK, (CANCLE_OPTION)},
    {KEY_CHANNEL_L, KEY_BUTTON_1, KEY_ACTION_LONG, (CANCLE_OPTION)},
    {KEY_CHANNEL_R, KEY_BUTTON_1, KEY_ACTION_LONG, (CANCLE_OPTION)},
    // {KEY_CHANNEL_LR, KEY_BUTTON_1, KEY_ACTION_LONG, (GAME_MODE)},
};

const u8 default_key_info_calling[KEY_CHANNEL_MAX * KEY_ACTION_MAX][4] = {  //对应通话中场景的默认按键功能
    {KEY_CHANNEL_L, KEY_BUTTON_1, KEY_ACTION_1_CLICK, (VOLUME_DOWN)},
    {KEY_CHANNEL_R, KEY_BUTTON_1, KEY_ACTION_1_CLICK, (VOLUME_UP)},
    {KEY_CHANNEL_L, KEY_BUTTON_1, KEY_ACTION_2_CLICK, (CALL_ANSWER_HANGUP)},
    {KEY_CHANNEL_R, KEY_BUTTON_1, KEY_ACTION_2_CLICK, (CALL_ANSWER_HANGUP)},
    {KEY_CHANNEL_L, KEY_BUTTON_1, KEY_ACTION_3_CLICK, (CANCLE_OPTION)},
    {KEY_CHANNEL_R, KEY_BUTTON_1, KEY_ACTION_3_CLICK, (CANCLE_OPTION)},
    {KEY_CHANNEL_L, KEY_BUTTON_1, KEY_ACTION_LONG, (CALL_REJECT)},
    {KEY_CHANNEL_R, KEY_BUTTON_1, KEY_ACTION_LONG, (CALL_REJECT)},
    // {KEY_CHANNEL_LR, KEY_BUTTON_1, KEY_ACTION_LONG, (GAME_MODE)},
};

//对应APP_KEY_SENCE的APP场景
const u8 **default_key_info[KEY_SENCE_MAX] = {
    default_key_info_call_in,
    default_key_info_hangup,
    default_key_info_all,
    default_key_info_calling,
};

接口使用方法

  1. 运行自定义按键的流程

普通SDK:

extern u8 app_key_deal(u8 from_tws, u8 key_value, u8 key_status);  
if(app_key_deal((u32)event->arg == KEY_EVENT_FROM_TWS, key->value, key->event)){​  
    printf("app define, break sdk default func\n");  
    return ret;  
​}  

image

可视化SDK:

见demo
2. app修改耳机的按键功能 使用函数:u8 extern_set_key_func(u8 ch, u8 sence, u8 key_value, u8 key_status, u8 func)
APP需要提供的信息:
1. 此次修改的是左耳还是右耳,对应得到ch,非TWS传KEY_CHANNEL_R 2. 此次修改的是什么场景下的按键功能,对应得到sence,不涉及可传KEY_SENCE_ALL 3. 此次修改的是哪个按键,对应得到key_value,只有一个按键一般填0 4. 此次修改的是哪个按键动作,对应得到key_status 5. 此次修改需要按键实现什么功能,对应得到func

/**
 * @brief 给APP修改按键的接口
 * 
 * @param ch APP_KEY_CHANNEL
 * @param sence APP_KEY_SENCE
 * @param key_value APP_KEY_BUTTON
 * @param key_status APP_KEY_ACTION
 * @param func Function
 * @return u8 1:按键冲突;0:正常设置
 */
u8 extern_set_key_func(u8 ch, u8 sence, u8 key_value, u8 key_status, u8 func)
{
    if(ch >= KEY_CHANNEL_MAX || sence >= KEY_SENCE_MAX || key_value >= KEY_BUTTON_MAX || key_status >= KEY_ACTION_MAX){
        return 1;
    }

    return extern_define_key_func(ch, sence, key_value, key_status, func);
}

  1. app获取(耳机上报)自定义按键功能 使用函数:u8 extern_get_key_func(u8 ch, u8 sence, u8 key_value, u8 key_status)
    获取某个自定义按键实现的功能,需要提供信息:
    1. 左耳还是右耳,对应得到ch
    2. 什么场景下的按键功能,对应得到sence
    3. 哪个按键,对应得到key_value
    4. 哪个按键动作,对应得到key_status 以上信息对应的按键功能通过函数的返回值返回
/**
 * @brief 给APP读取按键的接口
 * 
 * @param ch APP_KEY_CHANNEL
 * @param sence APP_KEY_SENCE
 * @param key_value APP_KEY_BUTTON
 * @param key_status APP_KEY_ACTION
 * @return u8 Function
 */
u8 extern_get_key_func(u8 ch, u8 sence, u8 key_value, u8 key_status)
{
    if(ch >= KEY_CHANNEL_MAX || sence >= KEY_SENCE_MAX || key_value >= KEY_BUTTON_MAX || key_status >= KEY_ACTION_MAX){
        return 0;
    }
#if APP_DEFINE_KEY_EN
    struct extern_define_key *define_key_p = &define_key[ch];
    u8 func = define_key_p->func[sence][key_value][key_status].func;
    printf("sence %s, channel %c, key %d, action %d, func %d\n", SENCE_NAME[sence], ch ? 'R' : 'L', key_value, key_status, func);
    return func;
#endif
    return 0;
}

//demo:可通过轮询定义的各个项目(操作类别、场景、按键值、按键动作)获得自定义按键的具体信息
/**
 * @brief 上报耳机本地保存的自定义按键,此为demo,需根据APP协议修改
 * 
 * @param cmd 
 */
void key_data_rsp(u8 cmd)
{
    extern u8 extern_get_key_func(u8 ch, u8 sence, u8 key_value, u8 key_status);
    u8 func_array[16];
    u8 func_num = 0;
    u8 function;
    for (u8 sence = 0; sence < 4; sence++) //按场景轮询
    {
        for (u8 ch = 0; ch < 2; ch++) //按左右耳轮询
        {
            for (u8 key_value = 0; key_value < 1; key_value++) //按按键值轮询
            {
                for (u8 key_status = 0; key_status < 4; key_status++) //按按键事件轮询
                {
                    function = extern_get_key_func(ch, sence, key_value, key_status);
                    if(function){//拿到功能
                        u8 app_key = 2 * key_status + ch;//转换为APP按键,比如左耳,长按
                        func_array[func_num++] = (app_key << 4) | function;//按照键值对的形式组合[按键:功能值],比如左耳长按:音量加,缓存到数组中
                    }
                }
            }
        }

        //将当前场景下的按键上报给APP,此为demo,需根据APP协议修改
        struct sound_peats_parse data;
        data.sof = SOF;
        data.length = 5 + func_num;
        data.cmd = (u8)cmd;
        data.flag = 0x00;
        data.pkg_num = sence;
        u8 rsp_buffer[sizeof(data) - 1 + 5 + func_num];
        u8 rsp_len = sizeof(data) - 1;
        memcpy(rsp_buffer, (u8 *)&data, sizeof(data) - 1);
        rsp_buffer[rsp_len++] = BIT(sence);
        rsp_buffer[rsp_len++] = 0xff;
        rsp_buffer[rsp_len++] = 0x1f;
        rsp_buffer[rsp_len++] = 0xff;
        rsp_buffer[rsp_len++] = 0x00;
        if(func_num){
            memcpy(rsp_buffer + rsp_len, func_array, func_num);
            rsp_len += func_num;
        }
        puts("send:");
        put_buf(rsp_buffer, rsp_len);
        multi_spp_send_data(0x0A, 0, rsp_buffer, rsp_len);//发数据
        func_num = 0;
    }
}
  1. 保存自定义按键 需要在include_lib\system\syscfg_id.h中定义一个新的VM索引(不要跟SDK已有的重复)
    例如:#define CFG_USER_CY_KEY 2
    关机时调用一下app_key_write_vm保存到VM。
/**
 * @brief 自定义按键保存到VM
 * 
 */
void app_key_write_vm(void)
{
#if APP_DEFINE_KEY_EN
    syscfg_write(CFG_USER_CY_KEY, define_key, sizeof(define_key));
#endif
}

image

本文档包含以下子页面

Prev
TWS配对常见应用
Next
AC700N 播歌双EQ DEMO示例及说明