中科藍(lán)訊SDK開發(fā)——SDK代碼解析
SDK結(jié)構(gòu)
1.1 SDK目錄結(jié)構(gòu)
└─app
├─platform
│ ├─bsp //底層外設(shè)相關(guān)
│ ├─functions //功能相關(guān)
│ ├─gui //顯示功能
│ ├─header
│ └─libs
└─projects //調(diào)用API
└─earphone
├─display //顯示
├─message //消息處理
├─Output //文件輸出
│ └─bin //音樂(lè)文件,配置
│ ├─res
│ │ ├─en
│ │ ├─eq
│ │ └─zh
│ └─Settings
│ └─Resources
│ ├─S6
│ │ ├─en
│ │ └─zh
│ └─TWS
│ ├─en
│ └─zh
├─plugin //插件
└─port //移植
1.1.1 bsp目錄
該目錄下,包含一些和底層硬件相關(guān)的數(shù)據(jù),函數(shù)初始化
├─bsp
│ bsp.h
│ bsp_audio.c
│ bsp_audio.h
│ bsp_aux.c
│ bsp_aux.h
│ bsp_ble.c
│ bsp_ble.h
│ bsp_bpap.c
│ bsp_bt.c
│ bsp_bt.h
│ bsp_charge.c
│ bsp_charge.h
│ bsp_cm.c
│ bsp_dac.c
│ bsp_dac.h
│ bsp_dump_buf_huart.c
│ bsp_eq.c
│ bsp_eq.h
│ bsp_fmrx.c
│ bsp_fmrx.h
│ bsp_fmtx.c
│ bsp_fmtx.h
│ bsp_fs.c
│ bsp_fs.h
│ bsp_hdmi.c
│ bsp_hdmi.h
│ bsp_hdmi_cec_msg.c
│ bsp_i2c.c
│ bsp_i2c.h
│ bsp_i2s.c
│ bsp_i2s.h
│ bsp_i2s_ta5711.c
│ bsp_i2s_ta5711.h
│ bsp_i2s_wm8978.c
│ bsp_i2s_wm8978.h
│ bsp_iap.c
│ bsp_id3_tag.c
│ bsp_id3_tag.h
│ bsp_iic_putchar.c
│ bsp_iis_ext.c
│ bsp_iis_ext.h
│ bsp_ir.c
│ bsp_ir.h
│ bsp_karaok.c
│ bsp_karaok.h
│ bsp_key.c
│ bsp_key.h
│ bsp_led.c
│ bsp_led.h
│ bsp_lrc.c
│ bsp_lrc.h
│ bsp_map.c
│ bsp_music.c
│ bsp_music.h
│ bsp_param.c
│ bsp_param.h
│ bsp_piano.c
│ bsp_piano.h
│ bsp_record.c
│ bsp_record.h
│ bsp_spiflash1.c
│ bsp_spiflash1.h
│ bsp_spiflash1_music_bin.c
│ bsp_spi_audio.h
│ bsp_spp.c
│ bsp_sys.c
│ bsp_sys.h
│ bsp_tkey.c
│ bsp_tkey.h
│ bsp_uart.c
1.1.2 functions目錄
主要包括藍(lán)牙功能的實(shí)現(xiàn),大部分的函數(shù)以庫(kù)函數(shù)的形式提供
├─functions
│ func.c
│ func.h
│ func_aux.c
│ func_aux.h
│ func_bt.c
│ func_bt.h
│ func_bt_dut.c
│ func_bt_dut.h
│ func_bt_hid.c
│ func_bt_hid.h
│ func_clock.c
│ func_clock.h
│ func_exspiflash_music.c
│ func_exspiflash_music.h
│ func_fmrx.c
│ func_fmrx.h
│ func_hdmi.c
│ func_hdmi.h
│ func_i2s.c
│ func_i2s.h
│ func_idle.c
│ func_idle.h
│ func_lowpwr.c
│ func_lowpwr.h
│ func_music.c
│ func_music.h
│ func_spdif.c
│ func_spdif.h
│ func_speaker.c
│ func_speaker.h
│ func_update.c
│ func_update.h
│ func_usbdev.c
│ func_usbdev.h
│ sfunc_bt_call.c
│ sfunc_bt_ota.c
│ sfunc_bt_ring.c
│ sfunc_record.c
│ sfunc_record.h
│ sfunc_record_play.c
│ sfunc_record_play.h
1.1.3 Message目錄
主要包括按鍵消息處理,是藍(lán)牙方案經(jīng)常需要改動(dòng)的目錄
├─message
│ msg_aux.c
│ msg_bt.c
│ msg_clock.c
│ msg_exspiflash_music.c
│ msg_fmrx.c
│ msg_hdmi.c
│ msg_i2s.c
│ msg_idle.c
│ msg_music.c
│ msg_record.c
│ msg_spdif.c
│ msg_speaker.c
│ msg_usbdev.c
1.1.4 Plugin目錄
音樂(lè)文件的調(diào)用,基本不會(huì)去修改這里
├─plugin
│ eq_table.c
│ multi_lang.c
│ multi_lang.h
│ plugin.c
│ plugin.h
1.1.5 Port目錄
主要包括硬件外設(shè)的調(diào)用,mani函數(shù)
└─port
port_earphone.c
port_earphone.h
port_ir.c
port_key.c
port_led.c
port_led.h
port_ledseg.c
port_linein.c
port_linein.h
port_mic.c
port_mic.h
port_mute.c
port_pwm.c
port_pwm.h
port_sd.c
port_sd.h
port_sd1.c
port_tkey.c
port_tkey.h
port_update.c
2 代碼運(yùn)行流程
2.1 初始化
//正常啟動(dòng)Main函數(shù)
int main(void)
{
printf("Hello AB533X!\n");
bsp_sys_init();
func_run();
return 0;
}
bsp_sys_init();函數(shù)主要包括各種功能的初始化,獲取download工具的配置。
func_run();主要是處理藍(lán)牙消息和硬件的消息。
2.2 各模式循環(huán)
初始化之后,進(jìn)入一個(gè)FUN函數(shù),藍(lán)牙耳機(jī)的FUN函數(shù)基本上都在跑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 藍(lán)牙模式
藍(lán)牙功能函數(shù)
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();的時(shí)候,SDK留給開發(fā)者處理的只有消息處理和電量檢測(cè),來(lái)電檢測(cè)等,藍(lán)牙耳機(jī)接收音頻信號(hào),解碼那些都是屏蔽起來(lái)的。
printf(“%s\n”, func);
2.3.1 進(jìn)入藍(lán)牙模式
藍(lán)牙入口函數(shù)
func_bt_enter();
主要執(zhí)行藍(lán)牙初始化,播報(bào)提示音
2.3.2 藍(lán)牙模式大循環(huán)
func_bt_process();
包括響鈴,通話,藍(lán)牙音樂(lè)
sfunc_bt_ring();
sfunc_bt_call();
func_bt_message(msg_dequeue());
消息處理
2.3.3 補(bǔ)充
C語(yǔ)言的特殊宏
LINE 表示正在編譯的文件的行號(hào)
FILE 表示正在編譯的文件的名字
DATE_ 表示編譯時(shí)刻的日期字符串,例如: “25 Dec 2007”
TIME 表示編譯時(shí)刻的時(shí)間字符串,例如: “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;
}
打印結(jié)果
speci_define.c
6
Jul 6 2019
00:46:39
2.4 消息
經(jīng)常需要改動(dòng)的部分
2.4.1 消息處理:
二次開發(fā)中修改最多的部分就是消息處理這一塊,按鍵消息處理的修改最多。按鍵消息有長(zhǎng)按,短按,雙擊,三擊,四擊,五擊等等
Func函數(shù)的為例
AT(.text.func.msg)
void func_message(u16 msg)
{
switch (msg) {
case KL_NEXT_VOL_UP://如果長(zhǎng)按NEXT_VOL_UP這個(gè)按鍵
if (sfunc_bt_call_flag) {
……
break;
}
……
}
2.4.2 消息來(lái)源:
以按鍵為例
void msg_enqueue(u16 msg);//消息隊(duì)列
在程序中執(zhí)行按鍵掃描函數(shù):
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
//需要放到最后處理,當(dāng)沒(méi)進(jìn)行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);//得到具體按下哪個(gè)按鍵
if (key != NO_KEY) {
//printf("enqueue: %04x\n", key);
if ((key & KEY_TYPE_MASK) == KEY_LONG_UP) {
msg_queue_detach(key | KEY_HOLD); //長(zhǎng)按抬鍵,先清掉HOLD按鍵消息
}
#if KEY_MSG_REMAP_EN
key_msg_remap(&key); //按鍵重映射.
#endif
msg_enqueue(key);//把消息放到消息隊(duì)列
}
return key_val;
}
2.4.3 按鍵消息的注意事項(xiàng):
下面的宏都是按鍵消息:
以PLAY按鍵為例
#define K_PLAY (KEY_PLAY | KEY_SHORT) //下降沿
#define KU_PLAY (KEY_PLAY | KEY_SHORT_UP) //上升沿
#define KL_PLAY (KEY_PLAY | KEY_LONG) //長(zhǎng)按
#define KLU_PLAY (KEY_PLAY | KEY_LONG_UP) //長(zhǎng)按上升沿
#define KH_PLAY (KEY_PLAY | KEY_HOLD) //長(zhǎng)按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) //五擊
注意!每次按鍵都會(huì)觸發(fā)下降沿。
以藍(lán)牙模式為例:
程序先在func_bt_message函數(shù)做判斷,如果在該函數(shù)沒(méi)有找到一致的case,則會(huì)跑到公共的消息處理函數(shù)中 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 應(yīng)用:1S消息
再定時(shí)器中,每隔一秒發(fā)送一個(gè)消息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++;
}
}
再藍(lán)牙消息或者公共消息做處理,常用的1秒消息處理有報(bào)告電量,連接藍(lán)牙自動(dòng)播放。
case MSG_SYS_1S:
bt_send_msg(BT_MSG_HFP_REPORT_BAT);
break;
2.4.5 藍(lán)牙消息函數(shù):
三個(gè)狀態(tài)的消息處理,藍(lán)牙模式比較特殊,除了一個(gè)func_bt_message還有兩個(gè),響鈴,通話。
響鈴:void sfunc_bt_ring_message(u16 msg)
來(lái)電響鈴的時(shí)候執(zhí)行消息處理,主要包括接/掛電話,電量報(bào)告和按鍵消息公共處理。
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();
通話過(guò)程的按鍵消息處理,主要包括音量調(diào)整,三方通話,電量報(bào)告
Music: void func_bt_message(u16 msg)
藍(lán)牙音樂(lè)模式的消息處理,上下曲切換,暫停播放,音量調(diào)整,報(bào)告電池電量等