#include "include.h" #define TRACE_EN 0 #if TRACE_EN #define TRACE(...) printf(__VA_ARGS__) #else #define TRACE(...) #endif #define EQ_CRC_SEED 0xffff bool bsp_eq_check_res_crc(u8 *eq_buf); void eq_tx_ack(u8 bank_num, u8 ack); void eq_dbg_huart_init(void); void tx_ack(uint8_t *packet, uint16_t len); u8 check_sum(u8 *buf, u16 size); void bt_call_test_set_mic(u8 flag); extern const char tbl_anc_header[3]; extern const char tbl_eq_version[10]; extern const int tbl_eq_gain[16]; AT(.rodata.eq.table) const eq_param music_eq_tbl[MUSIC_EQ_TBL_LEN] = { {&RES_BUF_EQ_NORMAL_EQ, &RES_LEN_EQ_NORMAL_EQ}, //normal {&RES_BUF_EQ_POP_EQ, &RES_LEN_EQ_POP_EQ}, //pop {&RES_BUF_EQ_JAZZ_EQ, &RES_LEN_EQ_JAZZ_EQ}, //jazz {&RES_BUF_EQ_ROCK_EQ, &RES_LEN_EQ_ROCK_EQ}, //rock {&RES_BUF_EQ_CLASSIC_EQ, &RES_LEN_EQ_CLASSIC_EQ},//classic {&RES_BUF_EQ_COUNTRY_EQ, &RES_LEN_EQ_COUNTRY_EQ},//country }; u8 eq_get_check_res_sel(void) { return EQ_CHECK_RES_SEL; } const u8* eq_get_check_res_buf(void) { return (const u8 *)RES_BUF_EQ_CHECK_RES_EQ; } AT(.text.eq) void music_set_eq_by_num(u8 num) { if (num > (MUSIC_EQ_TBL_LEN - 1)) { return; } music_set_eq_by_res(*music_eq_tbl[num].addr, *music_eq_tbl[num].len); } AT(.text.eq) void sys_set_eq(void) { sys_cb.eq_mode++; if (sys_cb.eq_mode > 5) { sys_cb.eq_mode = 0; } music_set_eq_by_num(sys_cb.eq_mode); } AT(.text.eq) void bt_sco_eq_drc_init(u32 msbc_flag) { u32 mic_eq_addr, mic_eq_len, mic_drc_addr, mic_drc_len; if (msbc_flag) { mic_eq_addr = RES_BUF_EQ_BT_MIC_16K_EQ; mic_eq_len = RES_LEN_EQ_BT_MIC_16K_EQ; mic_drc_addr = RES_BUF_EQ_BT_MIC_16K_DRC; mic_drc_len = RES_LEN_EQ_BT_MIC_16K_DRC; } else { mic_eq_addr = RES_BUF_EQ_BT_MIC_8K_EQ; mic_eq_len = RES_LEN_EQ_BT_MIC_8K_EQ; mic_drc_addr = RES_BUF_EQ_BT_MIC_8K_DRC; mic_drc_len = RES_LEN_EQ_BT_MIC_8K_DRC; } if (mic_set_eq_by_res(mic_eq_addr, mic_eq_len)) { xcfg_cb.mic_eq_en = 1; } else { xcfg_cb.mic_eq_en = 0; } mic_set_drc_by_res(mic_drc_addr, mic_drc_len); #ifdef RES_BUF_EQ_CALL_NORMAL_EQ music_set_eq_by_res(RES_BUF_EQ_CALL_NORMAL_EQ, RES_LEN_EQ_CALL_NORMAL_EQ); #else music_eq_off(); #endif #ifdef RES_BUF_EQ_CALL_DAC_DRC if (!music_set_drc_by_res(RES_BUF_EQ_CALL_DAC_DRC, RES_LEN_EQ_CALL_DAC_DRC)) { music_drc_off(); } #else music_drc_off(); #endif } void bt_sco_eq_drc_exit(void) { mic_drc_off(); mic_eq_off(); music_set_eq_by_num(sys_cb.eq_mode); music_set_drc_by_res(RES_BUF_EQ_DAC_DRC, RES_LEN_EQ_DAC_DRC); } void eq_tx_version(void) { // eq_tx_buf[0] = 'E'; // eq_tx_buf[1] = 'Q'; // eq_tx_buf[2] = '1'; //version // eq_tx_buf[3] = '*'; // eq_tx_buf[4] = 6; //size // eq_tx_buf[5] = 0; // eq_tx_buf[6] = 10; //band_cnt // eq_tx_buf[7] = 4; //param size // eq_tx_buf[8] = 5; //param cnt // eq_tx_buf[9] = 0; //rsvd memcpy(eq_tx_buf, tbl_eq_version, 10); #if ANC_EN eq_tx_buf[9] |= BIT(0); #endif u16 crc = calc_crc(eq_tx_buf, 10, EQ_CRC_SEED); eq_tx_buf[10] = crc; eq_tx_buf[11] = crc >> 8; tx_ack(eq_tx_buf, 12); } #if ANC_EN #define FF_EQ_NAME_NUM 4 static const char anc_fffb_eq_name[FF_EQ_NAME_NUM][13] = { "L0_NOS.EQ", "R0_NOS.EQ", "TP_L0_NOS.EQ", "TP_R0_NOS.EQ", }; bool bsp_eq_tws_sync_param(void) { u8 right_channel = 0; u8 anc_packet = eq_dbg_cb.anc_packet; if (anc_packet > 2) { anc_packet -= 2; } if (anc_packet > 1) { right_channel = 1; } if (xcfg_cb.bt_tws_en && (right_channel == func_bt_tws_get_channel())) { //声道不相等,转发 if(bt_tws_is_connected()) { bt_tws_sync(TWS_SYNC_INFO_EQ); } return true; } return false; } #endif #if BT_ALG_DBB_EN /* 该文件代码由Dynamic Bass Boost Tool (for 565X)生成。 */ AT(.text.rodata) const u8 dbb_coef_param[863] = { /* 滤波器类型:low shelf */ /* 中心频率:200 */ /* Q值:0.75 */ /* 增益:0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, */ 0x02, 0x15, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x00, 0x00, 0x00, 0x08, 0xda, 0xbe, 0xb9, 0x07, 0xb1, 0x5d, 0xb8, 0x0f, 0x50, 0xa2, 0x47, 0xf0, 0x27, 0x41, 0x46, 0xf8, 0x28, 0x10, 0x02, 0x08, 0xa5, 0xb8, 0xb9, 0x07, 0xe3, 0x66, 0xba, 0x0f, 0x78, 0xad, 0x45, 0xf0, 0x8d, 0x4b, 0x44, 0xf8, 0x4a, 0x21, 0x04, 0x08, 0xce, 0xa3, 0xb9, 0x07, 0x3f, 0x61, 0xbc, 0x0f, 0x8c, 0xc7, 0x43, 0xf0, 0xb3, 0x63, 0x42, 0xf8, 0xd6, 0x33, 0x06, 0x08, 0x52, 0x80, 0xb9, 0x07, 0x32, 0x4d, 0xbe, 0x0f, 0x30, 0xf0, 0x41, 0xf0, 0x3b, 0x89, 0x40, 0xf8, 0x3e, 0x48, 0x08, 0x08, 0x29, 0x4e, 0xb9, 0x07, 0x26, 0x2b, 0xc0, 0x0f, 0x0c, 0x27, 0x40, 0xf0, 0xcc, 0xbb, 0x3e, 0xf8, 0xf5, 0x5e, 0x0a, 0x08, 0x4c, 0x0d, 0xb9, 0x07, 0x81, 0xfb, 0xc1, 0x0f, 0xcd, 0x6b, 0x3e, 0xf0, 0x0c, 0xfb, 0x3c, 0xf8, 0x70, 0x78, 0x0c, 0x08, 0xae, 0xbd, 0xb8, 0x07, 0xa5, 0xbe, 0xc3, 0x0f, 0x1f, 0xbe, 0x3c, 0xf0, 0xa6, 0x46, 0x3b, 0xf8, 0x22, 0x95, 0x0e, 0x08, 0x43, 0x5f, 0xb8, 0x07, 0xf3, 0x74, 0xc5, 0x0f, 0xb5, 0x1d, 0x3b, 0xf0, 0x45, 0x9e, 0x39, 0xf8, 0x81, 0xb5, 0x10, 0x08, 0xf8, 0xf1, 0xb7, 0x07, 0xca, 0x1e, 0xc7, 0x0f, 0x44, 0x8a, 0x39, 0xf0, 0x96, 0x01, 0x38, 0xf8, 0x04, 0xda, 0x12, 0x08, 0xba, 0x75, 0xb7, 0x07, 0x83, 0xbc, 0xc8, 0x0f, 0x84, 0x03, 0x38, 0xf0, 0x4a, 0x70, 0x36, 0xf8, 0x23, 0x03, 0x15, 0x08, 0x72, 0xea, 0xb6, 0x07, 0x77, 0x4e, 0xca, 0x0f, 0x30, 0x89, 0x36, 0xf0, 0x12, 0xea, 0x34, 0xf8, 0x58, 0x31, 0x17, 0x08, 0x07, 0x50, 0xb6, 0x07, 0xfd, 0xd4, 0xcb, 0x0f, 0x05, 0x1b, 0x35, 0xf0, 0xa3, 0x6e, 0x33, 0xf8, 0x1e, 0x65, 0x19, 0x08, 0x5d, 0xa6, 0xb5, 0x07, 0x67, 0x50, 0xcd, 0x0f, 0xc6, 0xb8, 0x33, 0xf0, 0xb2, 0xfd, 0x31, 0xf8, 0xf1, 0x9e, 0x1b, 0x08, 0x54, 0xed, 0xb4, 0x07, 0x07, 0xc1, 0xce, 0x0f, 0x36, 0x62, 0x32, 0xf0, 0xf7, 0x96, 0x30, 0xf8, 0x50, 0xdf, 0x1d, 0x08, 0xcc, 0x24, 0xb4, 0x07, 0x2a, 0x27, 0xd0, 0x0f, 0x1d, 0x17, 0x31, 0xf0, 0x2c, 0x3a, 0x2f, 0xf8, 0xba, 0x26, 0x20, 0x08, 0xa0, 0x4c, 0xb3, 0x07, 0x1f, 0x83, 0xd1, 0x0f, 0x46, 0xd7, 0x2f, 0xf0, 0x0b, 0xe7, 0x2d, 0xf8, 0xb3, 0x75, 0x22, 0x08, 0xa7, 0x64, 0xb2, 0x07, 0x2e, 0xd5, 0xd2, 0x0f, 0x7d, 0xa2, 0x2e, 0xf0, 0x52, 0x9d, 0x2c, 0xf8, 0xbd, 0xcc, 0x24, 0x08, 0xb8, 0x6c, 0xb1, 0x07, 0xa1, 0x1d, 0xd4, 0x0f, 0x94, 0x78, 0x2d, 0xf0, 0xbf, 0x5c, 0x2b, 0xf8, 0x61, 0x2c, 0x27, 0x08, 0xa7, 0x64, 0xb0, 0x07, 0xbd, 0x5c, 0xd5, 0x0f, 0x5e, 0x59, 0x2c, 0xf0, 0x13, 0x25, 0x2a, 0xf8, 0x27, 0x95, 0x29, 0x08, 0x42, 0x4c, 0xaf, 0x07, 0xc6, 0x92, 0xd6, 0x0f, 0xb3, 0x44, 0x2b, 0xf0, 0x10, 0xf6, 0x28, 0xf8, 0x9a, 0x07, 0x2c, 0x08, 0x57, 0x23, 0xae, 0x07, 0xfe, 0xbf, 0xd7, 0x0f, 0x6c, 0x3a, 0x2a, 0xf0, 0x7a, 0xcf, 0x27, 0xf8, 0x00, 0x00, 0x00, 0x08, 0x61, 0xa6, 0xb3, 0x07, 0xa3, 0x04, 0xb2, 0x0f, 0x5e, 0xfb, 0x4d, 0xf0, 0xa0, 0x59, 0x4c, 0xf8, 0xfd, 0x3e, 0x02, 0x08, 0xc1, 0x9f, 0xb3, 0x07, 0x14, 0x3c, 0xb4, 0x0f, 0x00, 0xdc, 0x4b, 0xf0, 0x56, 0x39, 0x4a, 0xf8, 0x15, 0x7f, 0x04, 0x08, 0x41, 0x89, 0xb3, 0x07, 0x5f, 0x63, 0xb6, 0x0f, 0xe3, 0xcc, 0x49, 0xf0, 0xec, 0x27, 0x48, 0xf8, 0xc6, 0xc0, 0x06, 0x08, 0xdc, 0x62, 0xb3, 0x07, 0xf9, 0x7a, 0xb8, 0x0f, 0xa5, 0xcd, 0x47, 0xf0, 0xfd, 0x24, 0x46, 0xf8, 0x8b, 0x04, 0x09, 0x08, 0x8c, 0x2c, 0xb3, 0x07, 0x55, 0x83, 0xba, 0x0f, 0xea, 0xdd, 0x45, 0xf0, 0x28, 0x30, 0x44, 0xf8, 0xe1, 0x4a, 0x0b, 0x08, 0x49, 0xe6, 0xb2, 0x07, 0xe2, 0x7c, 0xbc, 0x0f, 0x56, 0xfd, 0x43, 0xf0, 0x0e, 0x49, 0x42, 0xf8, 0x47, 0x94, 0x0d, 0x08, 0x06, 0x90, 0xb2, 0x07, 0x0c, 0x68, 0xbe, 0x0f, 0x92, 0x2b, 0x42, 0xf0, 0x52, 0x6f, 0x40, 0xf8, 0x3b, 0xe1, 0x0f, 0x08, 0xb3, 0x29, 0xb2, 0x07, 0x3d, 0x45, 0xc0, 0x0f, 0x4b, 0x68, 0x40, 0xf0, 0x99, 0xa2, 0x3e, 0xf8, 0x3f, 0x32, 0x12, 0x08, 0x3f, 0xb3, 0xb1, 0x07, 0xd9, 0x14, 0xc2, 0x0f, 0x30, 0xb3, 0x3e, 0xf0, 0x8b, 0xe2, 0x3c, 0xf8, 0xd4, 0x87, 0x14, 0x08, 0x95, 0x2c, 0xb1, 0x07, 0x45, 0xd7, 0xc3, 0x0f, 0xf5, 0x0b, 0x3d, 0xf0, 0xd1, 0x2e, 0x3b, 0xf8, 0x7d, 0xe2, 0x16, 0x08, 0x9c, 0x95, 0xb0, 0x07, 0xe0, 0x8c, 0xc5, 0x0f, 0x51, 0x72, 0x3b, 0xf0, 0x18, 0x87, 0x39, 0xf8, 0xbf, 0x42, 0x19, 0x08, 0x3a, 0xee, 0xaf, 0x07, 0x08, 0x36, 0xc7, 0x0f, 0xfe, 0xe5, 0x39, 0xf0, 0x0d, 0xeb, 0x37, 0xf8, 0x21, 0xa9, 0x1b, 0x08, 0x4f, 0x36, 0xaf, 0x07, 0x18, 0xd3, 0xc8, 0x0f, 0xb9, 0x66, 0x38, 0xf0, 0x60, 0x5a, 0x36, 0xf8, 0x2b, 0x16, 0x1e, 0x08, 0xbd, 0x6d, 0xae, 0x07, 0x68, 0x64, 0xca, 0x0f, 0x43, 0xf4, 0x36, 0xf0, 0xc3, 0xd4, 0x34, 0xf8, 0x66, 0x8a, 0x20, 0x08, 0x5d, 0x94, 0xad, 0x07, 0x4e, 0xea, 0xcb, 0x0f, 0x61, 0x8e, 0x35, 0xf0, 0xeb, 0x59, 0x33, 0xf8, 0x60, 0x06, 0x23, 0x08, 0x09, 0xaa, 0xac, 0x07, 0x1d, 0x65, 0xcd, 0x0f, 0xda, 0x34, 0x34, 0xf0, 0x8d, 0xe9, 0x31, 0xf8, 0xa7, 0x8a, 0x25, 0x08, 0x98, 0xae, 0xab, 0x07, 0x25, 0xd5, 0xce, 0x0f, 0x7b, 0xe7, 0x32, 0xf0, 0x61, 0x83, 0x30, 0xf8, 0xcc, 0x17, 0x28, 0x08, 0xdc, 0xa1, 0xaa, 0x07, 0xb7, 0x3a, 0xd0, 0x0f, 0x11, 0xa6, 0x31, 0xf0, 0x20, 0x27, 0x2f, 0xf8, 0x62, 0xae, 0x2a, 0x08, 0xa5, 0x83, 0xa9, 0x07, 0x1d, 0x96, 0xd1, 0x0f, 0x70, 0x70, 0x30, 0xf0, 0x86, 0xd4, 0x2d, 0xf8, 0xff, 0x4e, 0x2d, 0x08, 0xc0, 0x53, 0xa8, 0x07, 0xa2, 0xe7, 0xd2, 0x0f, 0x6d, 0x46, 0x2f, 0xf0, 0x51, 0x8b, 0x2c, 0xf8, 0x3c, 0xfa, 0x2f, 0x08, 0xf6, 0x11, 0xa7, 0x07, 0x8e, 0x2f, 0xd4, 0x0f, 0xe2, 0x27, 0x2e, 0xf0, 0x3e, 0x4b, 0x2b, 0xf8, }; #define BT_ALG_DBB_TABLE_LEVEL_MAX 20 //eq参数table最大20dB增益(不支持修改) #if BT_ALG_DBB_KEY_EN u8 bt_alg_dbb_on = 1; #endif #if EQ_CHECK_RES_SEL == 2 || EQ_CHECK_RES_SEL == 3 AT(.com_text.dbb) WEAK const u8 *music_dbb_eq_coef_enc_param_get(u8 *table_max_level, u8 *max_level, u8* dac_spr,u32 *len) { *table_max_level = BT_ALG_DBB_TABLE_LEVEL_MAX; * max_level = BT_ALG_DBB_LEVEL_MAX; * dac_spr = DAC_OUT_SPR; * len = sizeof(dbb_coef_param); return (u8*) &dbb_coef_param; } #else AT(.text.dbb) const s32 *music_dbb_eq_coef_param_get(u8 level) { u16 offset = 1 + 1 + BT_ALG_DBB_TABLE_LEVEL_MAX + 1; u16 total_len = (BT_ALG_DBB_TABLE_LEVEL_MAX + 1) * 20; if(level > BT_ALG_DBB_LEVEL_MAX) { level = BT_ALG_DBB_LEVEL_MAX; } if(DAC_OUT_SPR == DAC_OUT_48K) { return (s32*) &dbb_coef_param[offset + level * 20]; }else if (DAC_OUT_SPR == DAC_OUT_44K1) { return (s32*) &dbb_coef_param[offset + total_len + level * 20]; } return NULL; } #endif AT(.com_text.music) u8 bt_alg_dbb_is_enable(void) { return BT_ALG_DBB_EN; } #endif void eq_parse_cmd(void) { eq_dbg_cb.eq_spp_cb.rx_size = EQ_BUFFER_LEN; if (eq_rx_buf[0] != 'E' || eq_rx_buf[1] != 'Q') { return; } if (eq_rx_buf[2] == '?' && eq_rx_buf[3] == '#') { eq_tx_version(); return; } else if (eq_rx_buf[2] == '0' && eq_rx_buf[3] == ':') { eq_tx_ack(0, 0); eq_dbg_cb.anc_packet = 0; #if ANC_EN for (int i = 0; i < FF_EQ_NAME_NUM; i++) { if (strcmp(anc_fffb_eq_name[i], (char *)&eq_rx_buf[6]) == 0) { eq_dbg_cb.anc_packet = i + 1; if (!sys_cb.anc_start || sys_cb.anc_user_mode != 1) { bsp_anc_set_mode(1); } bsp_eq_tws_sync_param(); break; } } #endif return; } #if ANC_EN if (eq_dbg_cb.anc_packet && bsp_eq_tws_sync_param()) { delay_5ms(20); //wait tws send complete eq_tx_ack(eq_rx_buf[6], 0); return; } #endif // print_r(eq_rx_buf, EQ_BUFFER_LEN); if (!bsp_eq_check_res_crc(eq_rx_buf)) { return; } u8 band_cnt = eq_rx_buf[7]; #if ANC_EN if (eq_dbg_cb.anc_packet) { bsp_anc_dbg_eq_param(eq_dbg_cb.anc_packet, band_cnt, (u32 *)&eq_rx_buf[14]); } else #endif { music_set_eq(band_cnt, (u32 *)&eq_rx_buf[14]); } // printf("%08x\n", little_endian_read_32(eq_rx_buf, 14)); // u8 k; // u32 *ptr = (u32 *)&eq_rx_buf[18]; // for (k = 0; k < band_cnt*5; k++) { // printf("%08x", *ptr++); // if (k % 5 == 4) { // printf("\n"); // } else { // printf(" "); // } // } memset(eq_rx_buf, 0, EQ_BUFFER_LEN); } #if ANC_EN void bsp_anc_dbg_ack_inquiry(void) { memset(eq_tx_buf, 0, 4); eq_tx_buf[0] = 'A'; eq_tx_buf[1] = 'N'; eq_tx_buf[2] = 'C'; eq_tx_buf[3] = '*'; tx_ack(eq_tx_buf, 4); } void bsp_anc_dbg_ack(u8 error_code) { memset(eq_tx_buf, 0, 4); eq_tx_buf[0] = 'Y'; eq_tx_buf[2] = error_code; eq_tx_buf[3] = check_sum(eq_tx_buf, 3); tx_ack(eq_tx_buf, 4); } void bsp_anc_parse_cmd(void) { u8 *ptr = eq_rx_buf; if (memcmp((char *)ptr, tbl_anc_header, 3) != 0) { return; } if (ptr[3] == '?') { bsp_anc_dbg_ack_inquiry(); return; } u16 size = ptr[4] + 3; u16 crc = calc_crc(ptr, size, 0xffff); if (crc != little_endian_read_16(ptr, size)) { bsp_anc_dbg_ack(1); //error code 1:crc error return; } u8 channel = ptr[5]; if (channel > 3 || channel == 0) { bsp_anc_dbg_ack(2); //error code 2:param error return; } if (!xcfg_cb.anc_en) { bsp_anc_dbg_ack(3); //error code 3:anc close return; } bsp_anc_parse_cmd_process(ptr); bsp_anc_dbg_ack(0); //error code 0:succeed } #endif #if SMIC_DBG_EN static void bsp_enc_dbg_ack(u8 channel, u8 errcode ) { u8 ack[4]; memset(ack, 0, 4); if(errcode>0){ ack[0] = 'N'; }else{ ack[0] = 'Y'; } ack[1] = channel; ack[2] = errcode; ack[3] = 0xff; tx_ack(ack, 4); } const char tbl_smic_header[4] = "SMIC"; void bsp_smic_parse_cmd(void) { u8 *ptr = eq_rx_buf; // printf("channel = %c;%c;%c\n",ptr[0],ptr[1],ptr[2]); if (memcmp((char *)ptr, tbl_smic_header, 4) != 0) { bsp_enc_dbg_ack(0, 1); //error code 1:head error return; } u8 channel = ptr[6]; u8 ctlcmd = ptr[7]; // printf("channel = %c; ctlcmd = %c\n",channel,ctlcmd); if(ctlcmd == 'N'){ //smic close bt_call_test_set_mic(1); bsp_enc_dbg_ack(channel, 0); //sucess }else if(ctlcmd == 'Y'){ //smic open bt_call_test_set_mic(0); bsp_enc_dbg_ack(channel, 0); //sucess }else{ bsp_enc_dbg_ack(channel, 3); //error code 3:ctlcmd error return; } } #endif void eq_dbg_init(void) { #if VUSB_TBOX_QTEST_EN if(get_qtest_mode()){ return; } #endif memset(eq_rx_buf, 0, EQ_BUFFER_LEN); memset(&eq_dbg_cb, 0, sizeof(eq_dbg_cb_t)); #if EQ_DBG_IN_UART eq_dbg_huart_init(); #endif }