SDKの構造
1.1 SDKのディレクトリ構造
└─app
├─platform
│ ├─bsp //底层外设相关
│ ├─functions //功能相关
│ ├─gui //显示功能
│ ├─header
│ └─libs
└─projects //调用API
└─earphone
├─display //显示
├─message //消息处理
├─Output //文件输出
│ └─bin //音乐文件,配置
│ ├─res
│ │ ├─en
│ │ ├─eq
│ │ └─zh
│ └─Settings
│ └─Resources
│ ├─S6
│ │ ├─en
│ │ └─zh
│ └─TWS
│ ├─en
│ └─zh
├─plugin //插件
└─port //移植
1.1.1 BSPディレクトリ
このディレクトリには、それとは根本的なハードウェア、機能の初期化に関連するデータが含まれています
1.1.2機能ディレクトリ
ほとんどの機能のライブラリ関数の形で提供するなど、Bluetooth対応の機能、
1.1.3メッセージの内容
キーメッセージングなど、Bluetoothは多くの場合、ディレクトリの変更が必要
1.1.4プラグインディレクトリ
コール音楽ファイルは、ここでは基本的な意志を行っていない変更します
1.1.5ポートのディレクトリ
コール、マニ機能のハードウェア周辺機器を含みます
2つのコード実行中のプロセス
2.1初期化
//正常启动Main函数
int main(void)
{
printf("Hello AB533X!\n");
bsp_sys_init();
func_run();
return 0;
}
bsp_sys_init()関数は、様々な機能の初期化を含む構成のダウンロードツールを入手します。
func_run();主にブルートゥース・メッセージとメッセージ処理ハードウェア。
2.2各モードサイクル
初期化後、関数FUNを入力し、FUN Bluetoothヘッドセット機能は、実行func_btに基本的です
void func_run(void)
{
printf("%s\n", __func__);
//func_cb.sta = FUNC_AUX;
while (1) {
func_clear();
switch (func_cb.sta) {
#if FUNC_BT_EN
case FUNC_BT:
func_bt();
break;
#endif
#if FUNC_BTHID_EN
case FUNC_BTHID:
func_bthid();
break;
#endif // FUNC_BTHID_EN
#if FUNC_AUX_EN
case FUNC_AUX:
func_aux();
break;
#endif // FUNC_AUX_EN
case FUNC_PWROFF:
func_pwroff(sys_cb.pwrdwn_tone_en);
break;
case FUNC_BT_CBT:
func_bt_cbt();
break;
default:
func_exit();
break;
}
}
}
2.3 Bluetoothモード
AT(.text.func.bt)
void func_bt(void)
{
printf("func_bt\n");
func_bt_enter();
while (func_cb.sta == FUNC_BT) {
func_bt_process();
func_bt_message(msg_dequeue());
}
func_bt_exit();
}
プログラム)(func_btを行った;時間は、電池検出、呼び出し検出処理のみメッセージSDK開発プロセスを残し、Bluetoothヘッドセットは、これらのデコードが遮蔽され、オーディオ信号を受信します。
printf( "%S \ N-"、FUNC)。
2.3.1 Bluetoothのモードに入ります
func_bt_enter();
主にブルートゥース、ブロードキャスト・トーンの初期化を実行
2.3.2 Bluetoothモードサイクル
; func_bt_process()
、ブルートゥース音楽、リンギング呼び出しを含む
sfunc_bt_ringを();
sfunc_bt_call();
func_bt_message(msg_dequeue());
メッセージ処理
2.3.3補足
C语言的特殊宏
LINE 表示正在编译的文件的行号
FILE 表示正在编译的文件的名字
DATE_ 表示编译时刻的日期字符串,例如: “25 Dec 2007”
TIME 表示编译时刻的时间字符串,例如: “12:30:55”
#include <stdio.h>
int main(void)
{
printf("%s\r\n",__FILE__);
printf("%d\r\n",__LINE__);
printf("%s\r\n",__DATE__);
printf("%s\r\n",__TIME__);
return 0;
}
打印结果
speci_define.c
6
Jul 6 2019
00:46:39
2.4 消息
经常需要改动的部分
2.4.1 消息处理:
二次开发中修改最多的部分就是消息处理这一块,按键消息处理的修改最多。按键消息有长按,短按,双击,三击,四击,五击等等
Func函数的为例
AT(.text.func.msg)
void func_message(u16 msg)
{
switch (msg) {
case KL_NEXT_VOL_UP://如果长按NEXT_VOL_UP这个按键
if (sfunc_bt_call_flag) {
……
break;
}
……
}
2.4.2 消息来源:
以按键为例
void msg_enqueue(u16 msg);//消息队列
在程序中执行按键扫描函数:
u8 bsp_key_scan(void)
{
u8 key_val = NO_KEY;
u16 key = NO_KEY;
pwrkey_2_hw_pwroff_detect();
if (!get_adc_val()) {
return NO_KEY;
}
#if USER_ADKEY
key_val = get_adkey(adc_cb.key_val, xcfg_cb.user_adkey_en);
#endif // USER_ADKEY
#if USER_ADKEY2
if (key_val == NO_KEY) {
key_val = get_adkey2();
}
#endif // USER_ADKEY2
#if USER_IOKEY
if (key_val == NO_KEY) {
key_val = get_iokey();
}
#endif // USER_IOKEY
#if USER_PWRKEY
if (key_val == NO_KEY) {
key_val = get_pwrkey();
}
#endif // USER_PWRKEY
#if VBAT_DETECT_EN
sys_cb.vbat = get_vbat_val();
#endif // VBAT_DETECT_EN
#if (IRRX_SW_EN || IRRX_HW_EN)
if (key_val == NO_KEY) {
key_val = get_irkey();
}
#endif // (IRRX_SW_EN || IRRX_HW_EN)
#if USER_ADKEY_MUX_SDCLK
//需要放到最后处理,当没进行adc convert需要返回
if (key_val == NO_KEY) {
if (!adc_cb.sdclk_valid) {
return NO_KEY;
}
key_val = get_adkey(adc_cb.sdclk_val, xcfg_cb.user_adkey_mux_sdclk_en);
}
#endif // USER_ADKEY_MUX_SDCLK
key = bsp_key_process(key_val);//得到具体按下哪个按键
if (key != NO_KEY) {
//printf("enqueue: %04x\n", key);
if ((key & KEY_TYPE_MASK) == KEY_LONG_UP) {
msg_queue_detach(key | KEY_HOLD); //长按抬键,先清掉HOLD按键消息
}
#if KEY_MSG_REMAP_EN
key_msg_remap(&key); //按键重映射.
#endif
msg_enqueue(key);//把消息放到消息队列
}
return key_val;
}
2.4.3 按键消息的注意事项:
下面的宏都是按键消息:
以PLAY按键为例
#define K_PLAY (KEY_PLAY | KEY_SHORT) //下降沿
#define KU_PLAY (KEY_PLAY | KEY_SHORT_UP) //上升沿
#define KL_PLAY (KEY_PLAY | KEY_LONG) //长按
#define KLU_PLAY (KEY_PLAY | KEY_LONG_UP) //长按上升沿
#define KH_PLAY (KEY_PLAY | KEY_HOLD) //长按2秒左右
#define KD_PLAY (KEY_PLAY | KEY_DOUBLE) //双击
#define KTH_PLAY (KEY_PLAY | KEY_THREE) //三击
#define KFO_PLAY (KEY_PLAY | KEY_FOUR) //四击
#define KFI_PLAY (KEY_PLAY | KEY_FIVE) //五击
注意!每次按键都会触发下降沿。
以蓝牙模式为例:
程序先在func_bt_message函数做判断,如果在该函数没有找到一致的case,则会跑到公共的消息处理函数中 void func_message(u16 msg) 再做判断。
AT(.text.func.bt.msg)
void func_bt_message(u16 msg)
{
switch (msg) {
case KU_PLAY:
case KU_PLAY_POWER:
case KU_PLAY_MODE:
bt_music_play_pause();
f_bt.pp_2_unmute = sys_cb.mute;
break;
case KU_PREV_VOL_DOWN:
case KL_VOL_DOWN_PREV:
case KU_PREV:
bt_music_prev();
sys_cb.key2unmute_cnt = 15 * sys_cb.mute;
break;
……
default:
func_message(msg);
break;
2.4.4 应用:1S消息
再定时器中,每隔一秒发送一个消息MSG_SYS_1S
msg_enqueue(MSG_SYS_1S);
void usr_tmr5ms_isr(void)
{
//1s timer process
if ((tmr5ms_cnt % 200) == 0) {
msg_enqueue(MSG_SYS_1S);
tmr5ms_cnt = 0;
sys_cb.lpwr_warning_cnt++;
}
}
再蓝牙消息或者公共消息做处理,常用的1秒消息处理有报告电量,连接蓝牙自动播放。
case MSG_SYS_1S:
bt_send_msg(BT_MSG_HFP_REPORT_BAT);
break;
2.4.5 蓝牙消息函数:
三个状态的消息处理,蓝牙模式比较特殊,除了一个func_bt_message还有两个,响铃,通话。
响铃:void sfunc_bt_ring_message(u16 msg)
来电响铃的时候执行消息处理,主要包括接/挂电话,电量报告和按键消息公共处理。
AT(.text.func.btring.msg)
void sfunc_bt_ring_message(u16 msg)
{
switch (msg) {
case KU_PLAY:
case KU_HSF: //接听
case KU_PLAY_POWER:
case KU_PLAY_MODE:
bsp_clr_mute_sta();
bt_call_answer_incoming();
break;
case KD_PLAY:
case KL_HSF:
case KD_HSF:
bsp_clr_mute_sta();
bt_call_terminate(); //挂断
break;
case MSG_SYS_1S:
bt_send_msg(BT_MSG_HFP_REPORT_BAT);
break;
default:
func_message(msg);
break;
}
}
通话中:sfunc_bt_call_message();
通话过程的按键消息处理,主要包括音量调整,三方通话,电量报告
ミュージック:無効func_bt_message(U16 MSG)
メッセージングのBluetooth音楽モード、音楽は音量、バッテリ電源や他のレポートを調整し、一時停止、再生、上下に切り替えると、