bsp_anc.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863
  1. #include "include.h"
  2. #include "bsp_anc_param_table.h"
  3. #define TRACE_EN 1
  4. #if TRACE_EN
  5. #define TRACE(...) printf(__VA_ARGS__)
  6. #else
  7. #define TRACE(...)
  8. #endif
  9. uint calc_crc(void *buf, uint len, uint seed);
  10. void bsp_param_read(u8 *buf, u32 addr, uint len);
  11. void bsp_param_write(u8 *buf, u32 addr, uint len);
  12. extern uint os_spiflash_read(void *buf, u32 addr, uint len);
  13. #if ANC_EQ_RES2_EN
  14. static u8 anc_temp_buf[EQ_BUFFER_LEN] AT(.anc_res2_buf);
  15. #endif
  16. #if ANC_EN
  17. /****************************** ANC通路按照下表固定 **************************************
  18. * MODE_TWS_FFFB: 输入:mic2(FF/FB) 输出DACL
  19. * MODE_FFFB: 输入:mic2、3(FF/FB) 输出DACL/R (mic2->dacl,mic3->dacr)
  20. * MODE_TWS_HYBRID: 输入:mic2、3(Hybrid) 输出DACL
  21. * MODE_HYBRID: 输入:mic0、1、2、3(Hybrid) 输出DACL/R (mic01->dacl,mic23->dacr)
  22. *****************************************************************************************/
  23. static anc_channel_t channel_0 = {
  24. .mic_ch = MIC2,
  25. .msc_dly = 0,
  26. .bypass = 0,
  27. .drc.drc_en = 0,
  28. .drc.filter_en = 0,
  29. .drc.drc_after_eq = 0,
  30. };
  31. static anc_channel_t channel_1 = {
  32. .mic_ch = MIC3,
  33. .msc_dly = 0,
  34. .bypass = 0,
  35. .drc.drc_en = 1,
  36. .drc.filter_en = 0,
  37. .drc.drc_after_eq = 0,
  38. };
  39. static anc_channel_t channel_2 = {
  40. .mic_ch = MIC0,
  41. .msc_dly = 0,
  42. .bypass = 0,
  43. .drc.drc_en = 0,
  44. .drc.filter_en = 0,
  45. .drc.drc_after_eq = 0,
  46. };
  47. static anc_channel_t channel_3 = {
  48. .mic_ch = MIC1,
  49. .msc_dly = 0,
  50. .bypass = 0,
  51. .drc.drc_en = 1,
  52. .drc.filter_en = 0,
  53. .drc.drc_after_eq = 0,
  54. };
  55. struct anc_cfg_t anc_cfg = {
  56. .spr = SPR_384000,
  57. .ch[0] = &channel_0,
  58. .ch[1] = &channel_1,
  59. .ch[2] = &channel_2,
  60. .ch[3] = &channel_3,
  61. .fade_in_step = 12,
  62. .fade_out_step = 12,
  63. .change_en = 0,
  64. .dc_rm = ANC_DCRM_EN,
  65. .fade_en = 1,
  66. .order = 1,
  67. };
  68. static u32 anc_dbg_cache[8][51] AT(.anc_dbg_buf);
  69. #if ANC_MAX_VOL_DIS_FB_EN
  70. static u32 anc_max_vol_dis_fb_tick = 0;
  71. static u8 anc_max_vol_process_sta = 0;
  72. static u8 anc_max_vol_dac_vol_sta = 0;
  73. static u8 anc_max_vol_change_cnt = 0;
  74. #endif // ANC_MAX_VOL_DIS_FB_EN
  75. #define EQ_GAIN_STEP 2 //0.2dB
  76. AT(.text.update)
  77. void bsp_get_anctrim(u8 trimbuf[2])
  78. {
  79. bsp_param_read(&trimbuf[0], PARAM_ANC_MIC0_VAL, 1);
  80. bsp_param_read(&trimbuf[1], PARAM_ANC_MIC1_VAL, 1);
  81. }
  82. //计算校准增益
  83. static u32 bsp_anc_gain_adjust_do(u8 ch, s8 value)
  84. {
  85. s32 gain, abs_gain, adjust_val = 0;
  86. gain = (s32)sys_cb.mic_gain[ch];//初始gain值
  87. if (value != 0) {
  88. if (value >= 60 || value <= -60) {
  89. s8 value1 = (value >= 60) ? 59 : -59;
  90. s8 value2 = (value >= 60) ? (value - 59) : (value + 59);
  91. adjust_val = (s32)anc_pow10_cal(value1 * EQ_GAIN_STEP);
  92. s32 adjust_val2 = (s32)anc_pow10_cal(value2 * EQ_GAIN_STEP);
  93. //gain = ((s64)gain * adjust_val) >> ANC_FIX_BIT;
  94. //gain = ((s64)gain * adjust_val2) >> ANC_FIX_BIT;
  95. gain = (s32)muls_shift23(gain, adjust_val);
  96. gain = (s32)muls_shift23(gain, adjust_val2);
  97. TRACE("adjust_val %d %d\n", adjust_val, adjust_val2);
  98. } else {
  99. adjust_val = (s32)anc_pow10_cal(value * EQ_GAIN_STEP);
  100. //gain = ((s64)gain * adjust_val) >> ANC_FIX_BIT;
  101. gain = (s32)muls_shift23(gain, adjust_val);
  102. }
  103. abs_gain = gain > 0? gain : -gain;
  104. if (abs_gain > EQ_GAIN_MAX || abs_gain < EQ_GAIN_MIN) {
  105. TRACE("adjust gain overflow %d\n", abs_gain);
  106. return sys_cb.mic_gain[ch];
  107. }
  108. TRACE("anc ch[%d] adjust value:%d adjust_val:%d prev_gain:%d gain:%d\n", ch, value, adjust_val, sys_cb.mic_gain[ch], gain);
  109. }
  110. return (u32)gain;
  111. }
  112. //设置校准增益
  113. void bsp_anc_gain_adjust(u8 ch, s8 value)
  114. {
  115. if (anc_cfg.ch[ch] == NULL) {
  116. return;
  117. }
  118. sys_cb.adjust_val[ch] = value;
  119. anc_cfg.ch[ch]->nos_gain = bsp_anc_gain_adjust_do(ch, value);
  120. anc_set_param(); //更新参数
  121. }
  122. bool bsp_anc_res_check_crc(u32 addr, u32 len)
  123. {
  124. u8 *ptr = (u8 *)addr;
  125. u8 offset = 0;
  126. if (ptr[0] == 'E' && ptr[1] == 'q' && ptr[2] == 0x01) {
  127. offset = 4;
  128. }
  129. u8 band_cnt = ptr[3+offset];
  130. if (band_cnt > 10) { //最多支持10条降噪eq
  131. return false;
  132. }
  133. u32 res_crc = ptr[band_cnt*27+11+offset] << 8 | ptr[band_cnt*27+10+offset];
  134. u32 cal_crc = calc_crc(ptr, band_cnt*27+10+offset, 0xffff);
  135. //TRACE("res_crc %x, cal_crc %x\n", res_crc, cal_crc);
  136. if (res_crc == cal_crc) {
  137. return true;
  138. } else {
  139. return false;
  140. }
  141. }
  142. static void bsp_anc_set_nos_param(u8 ch, u8 band_cnt, const u32 *param)
  143. {
  144. if (anc_cfg.ch[ch] == NULL) {
  145. return;
  146. }
  147. anc_cfg.ch[ch]->nos_band = band_cnt;
  148. if (band_cnt == 0 || param == NULL) {
  149. return;
  150. }
  151. TRACE("bsp_anc_set_nos_param dbg mode (%d), band %d\n", ch, band_cnt);
  152. anc_cfg.ch[ch]->nos_gain = *param++;
  153. anc_cfg.ch[ch]->nos_param = param;
  154. }
  155. static void bsp_anc_set_msc_param(u8 ch, u8 band_cnt, const u32 *param)
  156. {
  157. if (anc_cfg.ch[ch] == NULL) {
  158. return;
  159. }
  160. anc_cfg.ch[ch]->msc_band = band_cnt;
  161. if (band_cnt == 0 || param == NULL) {
  162. return;
  163. }
  164. TRACE("bsp_anc_set_msc_param dbg mode (%d), band %d\n", ch, band_cnt);
  165. anc_cfg.ch[ch]->msc_gain = *param++;
  166. anc_cfg.ch[ch]->msc_param = param;
  167. }
  168. #if ANC_EQ_RES2_EN
  169. enum res2_sta {
  170. RES_LEN_VAL = BIT(0), //原来的anc资源文件是否有效
  171. RES2_LEN_VAL = BIT(1), //资源文件中是否预留res2文件
  172. };
  173. static bool bsp_anc_load_res2_addr(u32 *addr, u32 len, u32 addr2, u32 len2_addr)
  174. {
  175. u8 res_valid = 0;
  176. u32 res2_len = 0;
  177. u32 res2_addr = 0;
  178. if (len != 0) {
  179. res_valid |= RES_LEN_VAL;
  180. }
  181. addr2 += ANC_EQ_RES2_BASE_ADDR;
  182. len2_addr += ANC_EQ_RES2_BASE_ADDR;
  183. os_spiflash_read(&res2_len, len2_addr, 4);
  184. if (res2_len) {
  185. res_valid |= RES2_LEN_VAL;
  186. }
  187. if (res_valid == 0) {
  188. TRACE("res2 len is zero, len2_addr %x\n", len2_addr);
  189. return false;
  190. }
  191. if (res_valid & RES2_LEN_VAL) {
  192. if ((res_valid & RES_LEN_VAL) == 0 || ANC_EQ_RES2_FIRST_SELECT) {
  193. os_spiflash_read(&res2_addr, addr2, 4);
  194. os_spiflash_read(anc_temp_buf, res2_addr + ANC_EQ_RES2_BASE_ADDR, res2_len);
  195. *addr = (u32)anc_temp_buf;
  196. TRACE("anc_load_res2: drc_res2_addr %x res2_len%x addr %x ", res2_addr + ANC_EQ_RES2_BASE_ADDR, res2_len, addr);
  197. }
  198. }
  199. return true;
  200. }
  201. #endif
  202. //从资源文件中获取drc参数
  203. static u8 *bsp_anc_get_drc_addr_by_res(u32 addr, u32 len, u32 addr2, u32 len2_addr)
  204. {
  205. #if ANC_EQ_RES2_EN
  206. TRACE("bsp_anc_get_drc_addr_by_res len2_addr %x\n", len2_addr);
  207. if (!bsp_anc_load_res2_addr((u32 *)&addr, len, addr2, len2_addr)) {
  208. return NULL;
  209. }
  210. #endif
  211. u8 *ptr = (u8 *)addr;
  212. if (ptr[2] != 0x02) { //DRC V3
  213. return NULL;
  214. }
  215. u8 drc_cnt = ptr[7];
  216. u32 res_crc = ptr[drc_cnt * 17 + 41] << 8 | ptr[drc_cnt * 17 + 40];
  217. u32 cal_crc = calc_crc(ptr, drc_cnt * 17 + 40, 0xffff);
  218. if (res_crc != cal_crc) {
  219. return NULL;
  220. }
  221. return &ptr[8];
  222. }
  223. //从资源文件中获取drc eq参数
  224. static u32 *bsp_anc_get_drc_eq_addr_by_res(u8 ch, u32 addr, u32 len, u32 addr2, u32 len2_addr)
  225. {
  226. #if ANC_EQ_RES2_EN
  227. TRACE("bsp_anc_get_drc_eq_addr_by_res len2_addr %x\n", len2_addr);
  228. bsp_anc_load_res2_addr((u32 *)&addr, len, addr2, len2_addr);
  229. #endif
  230. if (!bsp_anc_res_check_crc(addr, len)) {
  231. return NULL;
  232. }
  233. u8 *ptr = (u8 *)addr;
  234. anc_cfg.ch[ch]->drc.filter_band = ptr[7];
  235. return (u32 *)&ptr[8];
  236. }
  237. //从资源文件中获取nos参数
  238. static int bsp_anc_set_nos_param_by_res(u8 ch, u32 addr, u32 len, u32 addr2, u32 len2_addr, u8 tp)
  239. {
  240. #if ANC_EQ_RES2_EN
  241. TRACE("bsp_anc_set_nos_param_by_res ch %d, len2_addr %x\n", ch, len2_addr);
  242. if (!bsp_anc_load_res2_addr((u32 *)&addr, len, addr2, len2_addr)) {
  243. return -1;
  244. }
  245. #endif
  246. if (!bsp_anc_res_check_crc(addr, len)) {
  247. return -2;
  248. }
  249. u8 *ptr = (u8 *)addr;
  250. u8 band_cnt = ptr[7];
  251. u32 *param = (u32 *)&ptr[8];
  252. if (anc_cfg.ch[ch] == NULL) {
  253. return -3;
  254. }
  255. bsp_anc_set_nos_param(ch, band_cnt, param);
  256. sys_cb.mic_gain[ch] = anc_cfg.ch[ch]->nos_gain; //保存资源文件中的gain值
  257. if (xcfg_cb.anc_gain_en) { //写入量产测试的Gain
  258. if(sys_cb.adjust_val[ch] != 0) {
  259. anc_cfg.ch[ch]->nos_gain = bsp_anc_gain_adjust_do(ch, sys_cb.adjust_val[ch + tp*4]);
  260. TRACE("ch %d reset mic dgain:%d %x\n", ch, sys_cb.adjust_val[ch], anc_cfg.ch[ch]->nos_gain);
  261. }
  262. }
  263. return 0;
  264. }
  265. //从资源文件中获取msc参数
  266. static int bsp_anc_set_msc_param_by_res(u8 ch, u32 addr, u32 len, u32 addr2, u32 len2_addr)
  267. {
  268. #if ANC_EQ_RES2_EN
  269. TRACE("bsp_anc_set_msc_param_by_res ch %d, len2_addr %x\n", ch, len2_addr);
  270. if (!bsp_anc_load_res2_addr((u32 *)&addr, len, addr2, len2_addr)) {
  271. return -1;
  272. }
  273. #endif
  274. if (!bsp_anc_res_check_crc(addr, len)) {
  275. return -2;
  276. }
  277. u8 *ptr = (u8 *)addr;
  278. u8 band_cnt = ptr[7];
  279. u32 *param = (u32 *)&ptr[8];
  280. if (anc_cfg.ch[ch] == NULL) {
  281. return -3;
  282. }
  283. bsp_anc_set_msc_param(ch, band_cnt, param);
  284. return 0;
  285. }
  286. void bsp_anc_set_mic_gain(u8 ch, u8 anl, u8 gain)
  287. {
  288. TRACE("anc ch[%d], set mic anl %d, gain %d\n", ch, anl, gain);
  289. anc_set_mic_gain(ch, anl, gain);
  290. }
  291. void bsp_anc_mic_mute(u8 ch, u8 mute)
  292. {
  293. TRACE("anc ch[%d] mute_set:%x\n", ch, mute);
  294. anc_mic_mute(ch, mute);
  295. }
  296. void bsp_anc_dig_mic_mute(u8 ch, u8 mute)
  297. {
  298. TRACE("anc ch[%d] mute_set:%x\n", ch, mute);
  299. anc_dig_mic_mute(ch, mute);
  300. }
  301. void bsp_anc_start(void)
  302. {
  303. dac_fade_in();
  304. if (sys_cb.anc_start == 0) {
  305. sys_cb.anc_start = 1;
  306. anc_start();
  307. }
  308. }
  309. void bsp_anc_stop(void)
  310. {
  311. if (sys_cb.anc_start) {
  312. sys_cb.anc_start = 0;
  313. anc_stop();
  314. }
  315. }
  316. #if ANC_ALG_EN
  317. void bsp_anc_set_mode_alg_do(u8 mode)
  318. {
  319. #if ANC_ALG_HOWLING_FB_EN
  320. if (mode == 2) { //通透下开启
  321. bsp_anc_alg_howling_fb_start();
  322. } else {
  323. bsp_anc_alg_howling_fb_stop();
  324. }
  325. #endif // ANC_ALG_HOWLING_FB_EN
  326. #if ANC_ALG_HOWLING_FF_EN
  327. if (mode) {
  328. bsp_anc_alg_howling_ff_start();
  329. } else {
  330. bsp_anc_alg_howling_ff_stop();
  331. }
  332. #endif // ANC_ALG_HOWLING_FF_EN
  333. #if ANC_ALG_LIMITER_FF_EN
  334. if (mode) {
  335. bsp_anc_alg_limiter_ff_start();
  336. } else {
  337. bsp_anc_alg_limiter_ff_stop();
  338. }
  339. #endif // ANC_ALG_LIMITER_FF_EN
  340. #if ANC_ALG_DUMP_FOR_ANC_MODE
  341. if (mode) {
  342. if (sys_cb.anc_alg_en == 1) {
  343. bsp_anc_alg_stop();
  344. }
  345. bsp_anc_alg_start(ANC_ALG_DUMP_TYPE);
  346. } else {
  347. bsp_anc_alg_stop();
  348. }
  349. #endif // ANC_ALG_DUMP_FOR_ANC_MODE
  350. }
  351. #endif // ANC_ALG_EN
  352. void bsp_anc_set_param(u8 tp)
  353. {
  354. int i;
  355. const anc_param *anc_tbl;
  356. const anc_param *drc_tbl;
  357. const anc_param *drc_eq_tbl;
  358. #if ANC_EQ_RES2_EN
  359. const anc_exparam *anc_tbl2;
  360. const anc_exparam *drc_tbl2;
  361. const anc_exparam *drc_eq_tbl2;
  362. #endif
  363. TRACE("ANC MODE ==> %d\n", xcfg_cb.anc_mode);
  364. if (anc_cfg.anc_mode >= MODE_TWS_HYBRID) {
  365. u8 channel = 0;
  366. #if BT_TWS_EN
  367. if(xcfg_cb.bt_tws_en){
  368. channel = !sys_cb.tws_left_channel;
  369. }
  370. #endif
  371. u8 tbl_offset = 0;
  372. if (anc_cfg.anc_mode == MODE_TWS_HYBRID) { //TWS HYBRID 区分左右声道,位移为4
  373. tbl_offset = 4;
  374. } else { //4mic HYBRID L0\L1\R0\R1都要配,位移为2
  375. channel = 0; //HYBRID MODE声道设为0,保证正确读取资源文件
  376. tbl_offset = 2;
  377. }
  378. #if HLW_UI
  379. if((tp == 0) || (tp == 1))
  380. {
  381. anc_tbl = &anc_hybrid_eq_tbl[tp][tbl_offset * channel];
  382. drc_tbl = &anc_hybrid_drc_tbl[tp][tbl_offset/2 * channel];
  383. drc_eq_tbl = &anc_hybrid_drc_eq_tbl[tp][tbl_offset/2 * channel];
  384. }
  385. else if(tp == 2)
  386. {
  387. anc_tbl = &anc_l_noise_eq_tbl[tbl_offset * channel];
  388. drc_tbl = &anc_l_noise_drc_tbl[tbl_offset/2 * channel];
  389. drc_eq_tbl = &anc_l_noise_drc_eq_tbl[tbl_offset/2 * channel];
  390. }
  391. #else
  392. anc_tbl = &anc_hybrid_eq_tbl[tp][tbl_offset * channel];
  393. drc_tbl = &anc_hybrid_drc_tbl[tp][tbl_offset/2 * channel];
  394. drc_eq_tbl = &anc_hybrid_drc_eq_tbl[tp][tbl_offset/2 * channel];
  395. #endif // HLW_UI
  396. #if ANC_EQ_RES2_EN
  397. anc_tbl2 = &anc_hybrid_eq_tbl2[tp][tbl_offset * channel];
  398. drc_tbl2 = &anc_hybrid_drc_tbl2[tp][tbl_offset/2 * channel];
  399. drc_eq_tbl2 = &anc_hybrid_drc_eq_tbl2[tp][tbl_offset/2 * channel];
  400. #endif
  401. } else {
  402. u8 eq_num = 0;
  403. u8 drc_num = 0;
  404. #if BT_TWS_EN
  405. if (anc_cfg.anc_mode == MODE_TWS_FFFB && xcfg_cb.bt_tws_en) {
  406. if (!sys_cb.tws_left_channel) { //TWS下FF/FB模式右声道取R的曲线给MICL
  407. eq_num = 2;
  408. drc_num = 1;
  409. }
  410. }
  411. #endif
  412. #if FUNC_AUX_EN && AUX_ANC_EN
  413. if ((func_cb.sta == FUNC_AUX) && (AUX_ANC_EN == 2)) { //AUX模式下开启FB mode
  414. eq_num = 2;
  415. drc_num = 1;
  416. }
  417. #endif
  418. anc_tbl = &anc_fffb_eq_tbl[4 * tp + eq_num];
  419. drc_tbl = &anc_fffb_drc_tbl[2 * tp + drc_num];
  420. drc_eq_tbl = &anc_fffb_drc_eq_tbl[2 * tp + drc_num];
  421. #if ANC_EQ_RES2_EN
  422. anc_tbl2 = &anc_fffb_eq_tbl2[4 * tp + eq_num];
  423. drc_tbl2 = &anc_fffb_drc_tbl2[2 * tp + drc_num];
  424. drc_eq_tbl2 = &anc_fffb_drc_eq_tbl2[2 * tp + drc_num];
  425. #endif
  426. }
  427. #if HLW_UI
  428. //anc on low 使用anc on的校准增益
  429. if(tp == 2)
  430. {
  431. tp = 0;
  432. }
  433. #endif // HLW_UI
  434. anc_set_tansparency_mode(tp);
  435. for (i = 0; i < 4; i++) {
  436. if (anc_cfg.ch[i] == NULL) {
  437. continue;
  438. }
  439. u32 *drc_addr, *drc_eq_addr;
  440. #if ANC_EQ_RES2_EN
  441. bsp_anc_set_nos_param_by_res(i, *anc_tbl[2*i].addr, *anc_tbl[2*i].len, anc_tbl2[2*i].addr, anc_tbl2[2*i].len, tp);
  442. bsp_anc_set_msc_param_by_res(i, *anc_tbl[2*i+1].addr, *anc_tbl[2*i+1].len, anc_tbl2[2*i+1].addr, anc_tbl2[2*i+1].len);
  443. drc_addr = (u32 *)bsp_anc_get_drc_addr_by_res(*drc_tbl[i].addr, *drc_tbl[i].len, drc_tbl2[i].addr, drc_tbl2[i].len);
  444. drc_eq_addr = (u32 *)bsp_anc_get_drc_eq_addr_by_res(i, *drc_eq_tbl[i].addr, *drc_eq_tbl[i].len, drc_eq_tbl2[i].addr, drc_eq_tbl2[i].len);
  445. #else
  446. bsp_anc_set_nos_param_by_res(i, *anc_tbl[2*i].addr, *anc_tbl[2*i].len, 0, 0, tp);
  447. bsp_anc_set_msc_param_by_res(i, *anc_tbl[2*i+1].addr, *anc_tbl[2*i+1].len, 0, 0);
  448. drc_addr = (u32 *)bsp_anc_get_drc_addr_by_res(*drc_tbl[i].addr, *drc_tbl[i].len, 0, 0);
  449. drc_eq_addr = (u32 *)bsp_anc_get_drc_eq_addr_by_res(i, *drc_eq_tbl[i].addr, *drc_eq_tbl[i].len, 0, 0);
  450. #endif
  451. if (drc_addr != NULL) {
  452. anc_cfg.ch[i]->drc.drc_coef = drc_addr;
  453. }
  454. if (drc_eq_addr != NULL) {
  455. anc_cfg.ch[i]->drc.filter_coef = drc_eq_addr;
  456. }
  457. }
  458. anc_set_param(); //更新参数
  459. }
  460. //mode: 0[off], 1[anc], 2[tansparency]
  461. void bsp_anc_set_mode(u8 mode)
  462. {
  463. if (!xcfg_cb.anc_en) {
  464. return;
  465. }
  466. #if DAC_DNC_EN
  467. if (mode){ //anc生效时,不开启dnc检测
  468. dac_dnc_stop();
  469. }
  470. #endif
  471. sys_cb.anc_user_mode = mode;
  472. if (mode == 0) {
  473. #if HLW_UI
  474. hlw_func_set_auto_poweroff(true);
  475. #endif // HLW_UI
  476. bsp_anc_stop();
  477. bsp_anc_exit();
  478. } else {
  479. #if HLW_UI
  480. hlw_func_set_auto_poweroff(false);
  481. #endif // HLW_UI
  482. bsp_anc_init();
  483. bsp_anc_set_param(mode - 1);
  484. bsp_anc_start();
  485. }
  486. #if ANC_ALG_EN
  487. #if ASR_EN
  488. if (sys_cb.asr_enable) {
  489. bsp_asr_stop();
  490. sys_cb.asr_enable = 0;
  491. }
  492. #endif
  493. bsp_anc_set_mode_alg_do(mode);
  494. #endif // ANC_ALG_EN
  495. #if DAC_DNC_EN
  496. if (!mode && !sco_is_connected()){ //关闭anc时,开启dac检测
  497. dac_dnc_start();
  498. }
  499. #endif
  500. TRACE("anc user mode:%d\n", mode);
  501. #if HLW_UI
  502. if((sys_cb.anc_user_mode == 1)||(sys_cb.anc_user_mode == 0x03)) // anc on anc on low
  503. {
  504. bsp_anc_mic_mute(0, 0);
  505. bsp_anc_mic_mute(2, 0);
  506. bsp_anc_mic_mute(1, 0);
  507. bsp_anc_mic_mute(3, 0);
  508. }
  509. else if(sys_cb.anc_user_mode == 2) //anc aa
  510. {
  511. bsp_anc_mic_mute(0, 0);
  512. bsp_anc_mic_mute(2, 0);
  513. bsp_anc_mic_mute(1, 1);
  514. bsp_anc_mic_mute(3, 1);
  515. }
  516. #endif // HLW_UI
  517. }
  518. //无线/uart调anc参数接口
  519. void bsp_anc_dbg_eq_param(u8 packet, u8 band_cnt, u32 *eq_buf)
  520. {
  521. if (!xcfg_cb.anc_en) {
  522. return;
  523. }
  524. TRACE("anc dbg:%d %d\n", packet, band_cnt);
  525. if (packet > 8) {
  526. anc_set_tansparency_mode(1);
  527. packet -= 8;
  528. } else {
  529. anc_set_tansparency_mode(0);
  530. }
  531. #if BT_TWS_EN
  532. if (xcfg_cb.anc_mode == MODE_TWS_FFFB && xcfg_cb.bt_tws_en) { //TWS下FF/FB模式只调试MICL
  533. while (packet > 2) {
  534. packet -= 2;
  535. }
  536. }
  537. #endif
  538. u8 eq_sel = packet = packet - 1;
  539. memcpy(anc_dbg_cache[packet], eq_buf, ((band_cnt * 5) + 1) * 4);
  540. u8 ch_get = 0;
  541. if (anc_cfg.anc_mode == MODE_HYBRID) {
  542. ch_get = eq_sel / 2;
  543. } else {
  544. if (eq_sel == 0 || eq_sel == 1 || eq_sel == 4 || eq_sel == 5) { //L0_NOS.EQ, R0_NOS.EQ, L0_MSC.EQ, R0MSC.EQ
  545. ch_get = 0;
  546. } else if (eq_sel == 2 || eq_sel == 3 || eq_sel == 6 || eq_sel == 7) { //L1_NOS.EQ, R1_NOS.EQ, L1_MSC.EQ, R1_MSC.EQ
  547. ch_get = 1;
  548. }
  549. }
  550. if (packet % 2) {
  551. bsp_anc_set_msc_param(ch_get, band_cnt, anc_dbg_cache[packet]);
  552. } else {
  553. bsp_anc_set_nos_param(ch_get, band_cnt, anc_dbg_cache[packet]);
  554. }
  555. anc_set_param(); //更新参数
  556. }
  557. void bsp_anc_fade_enable(u8 enable)
  558. {
  559. anc_cfg.fade_en = enable;
  560. }
  561. void bsp_anc_init(void)
  562. {
  563. int i, cnt = 0;
  564. if (!xcfg_cb.anc_en) {
  565. TRACE("'xcfg_cb.anc_en' define 0\n");
  566. return;
  567. }
  568. if (sys_cb.anc_init) {
  569. return;
  570. }
  571. //初始化参数
  572. for (i = 0; i < 4; i++) {
  573. #if ANC_EQ_RES2_EN
  574. bsp_anc_set_nos_param_by_res(i, *anc_fffb_eq_tbl[cnt].addr, *anc_fffb_eq_tbl[cnt].len, anc_fffb_eq_tbl2[cnt].addr, anc_fffb_eq_tbl2[cnt].len, 0);
  575. cnt++;
  576. bsp_anc_set_msc_param_by_res(i, *anc_fffb_eq_tbl[cnt].addr, *anc_fffb_eq_tbl[cnt].len, anc_fffb_eq_tbl2[cnt].addr, anc_fffb_eq_tbl2[cnt].len);
  577. cnt++;
  578. #else
  579. bsp_anc_set_nos_param_by_res(i, *anc_fffb_eq_tbl[cnt].addr, *anc_fffb_eq_tbl[cnt].len, 0, 0, 0);
  580. cnt++;
  581. bsp_anc_set_msc_param_by_res(i, *anc_fffb_eq_tbl[cnt].addr, *anc_fffb_eq_tbl[cnt].len, 0, 0);
  582. cnt++;
  583. #endif
  584. }
  585. #if FUNC_AUX_EN && AUX_ANC_EN
  586. if (func_cb.sta == FUNC_AUX) {
  587. anc_cfg.anc_mode = MODE_FFFB;
  588. u8 aux_anc_type = AUX_ANC_EN;
  589. if (aux_anc_type == 1) { //FF mode
  590. anc_cfg.ch[0]->mic_ch = MIC0;
  591. anc_cfg.ch[1]->mic_ch = MIC2;
  592. bsp_param_read((u8*)&sys_cb.adjust_val[0], PARAM_ANC_MIC0_VAL, 1);
  593. bsp_param_read((u8*)&sys_cb.adjust_val[1], PARAM_ANC_MIC2_VAL, 1);
  594. bsp_param_read((u8*)&sys_cb.adjust_val[4], PARAM_ANC_TP_MIC0_VAL, 1);
  595. bsp_param_read((u8*)&sys_cb.adjust_val[5], PARAM_ANC_TP_MIC2_VAL, 1);
  596. } else { //FB mode
  597. anc_cfg.ch[0]->mic_ch = MIC1;
  598. anc_cfg.ch[1]->mic_ch = MIC3;
  599. bsp_param_read((u8*)&sys_cb.adjust_val[0], PARAM_ANC_MIC1_VAL, 1);
  600. bsp_param_read((u8*)&sys_cb.adjust_val[1], PARAM_ANC_MIC3_VAL, 1);
  601. bsp_param_read((u8*)&sys_cb.adjust_val[4], PARAM_ANC_TP_MIC1_VAL, 1);
  602. bsp_param_read((u8*)&sys_cb.adjust_val[5], PARAM_ANC_TP_MIC3_VAL, 1);
  603. }
  604. anc_cfg.ch[2] = NULL;
  605. anc_cfg.ch[3] = NULL;
  606. } else
  607. #endif
  608. {
  609. anc_cfg.anc_mode = xcfg_cb.anc_mode;
  610. if (anc_cfg.anc_mode != MODE_HYBRID) { //如果不是立体声HYBRID,就只使用2个adc
  611. anc_cfg.ch[2] = NULL;
  612. anc_cfg.ch[3] = NULL;
  613. } else {
  614. anc_cfg.ch[0]->mic_ch = MIC0;
  615. anc_cfg.ch[1]->mic_ch = MIC1;
  616. anc_cfg.ch[2]->mic_ch = MIC2;
  617. anc_cfg.ch[3]->mic_ch = MIC3;
  618. }
  619. if (anc_cfg.anc_mode == MODE_TWS_FFFB) { //如果是TWS的FFFB,只保留1个adc
  620. anc_cfg.ch[1] = NULL;
  621. }
  622. bsp_param_read((u8*)&sys_cb.adjust_val[0], PARAM_ANC_MIC0_VAL, 1);
  623. bsp_param_read((u8*)&sys_cb.adjust_val[1], PARAM_ANC_MIC1_VAL, 1);
  624. bsp_param_read((u8*)&sys_cb.adjust_val[2], PARAM_ANC_MIC2_VAL, 1);
  625. bsp_param_read((u8*)&sys_cb.adjust_val[3], PARAM_ANC_MIC3_VAL, 1);
  626. bsp_param_read((u8*)&sys_cb.adjust_val[4], PARAM_ANC_TP_MIC0_VAL, 1);
  627. bsp_param_read((u8*)&sys_cb.adjust_val[5], PARAM_ANC_TP_MIC1_VAL, 1);
  628. bsp_param_read((u8*)&sys_cb.adjust_val[6], PARAM_ANC_TP_MIC2_VAL, 1);
  629. bsp_param_read((u8*)&sys_cb.adjust_val[7], PARAM_ANC_TP_MIC3_VAL, 1);
  630. }
  631. anc_init(&anc_cfg);
  632. sys_cb.anc_init = 1;
  633. TRACE("anc init\n");
  634. TRACE("anc mode:%d\n", anc_cfg.anc_mode);
  635. TRACE("anc adjust mic gain:%d %d\n", sys_cb.adjust_val[0], sys_cb.adjust_val[1]);
  636. #if TRACE_EN
  637. for (u8 i=0; i<8; i++) {
  638. TRACE("adjust_val[%d]: %d\n", i, sys_cb.adjust_val[i]);
  639. }
  640. #endif
  641. }
  642. void bsp_anc_exit(void)
  643. {
  644. anc_exit();
  645. sys_cb.anc_init = 0;
  646. sys_cb.anc_start = 0;
  647. }
  648. #if ANC_MAX_VOL_DIS_FB_EN
  649. u8 bsp_anc_max_vol_dis_fb_get_sta(void)
  650. {
  651. return anc_max_vol_dac_vol_sta;
  652. }
  653. void bsp_anc_max_vol_set_vol(u8 max_vol)
  654. {
  655. s16 fb_gain = 0x7FFF;
  656. #if ANC_ALG_EN
  657. fb_gain = anc_alg_get_gain(1);
  658. #endif // ANC_ALG_EN
  659. if (max_vol) {
  660. fb_gain = 0x0000;
  661. }
  662. anc_vol_set(1, (u16)fb_gain, 0, 0, 12);
  663. // anc_vol_set(3, (u16)fb_gain, 0, 0, 12);
  664. anc_max_vol_dac_vol_sta = max_vol;
  665. TRACE("bsp_anc_max_vol_set_vol %d\n", max_vol);
  666. }
  667. AT(.com_text.anc.max_vol_dis_fb.dac_det)
  668. u8 bsp_anc_max_vol_dac_det_process(u32 pow)
  669. {
  670. u8 change = 0;
  671. u8 sta = anc_max_vol_dac_vol_sta;
  672. if (DAC_24BITS_EN) {
  673. pow = pow >> 8;
  674. }
  675. // printf("pow 0x%x\n", pow);
  676. if (anc_max_vol_dac_vol_sta) {
  677. if (pow < ANC_MAX_VOL_DIS_FB_DAC_THR) {
  678. change = 1;
  679. }
  680. } else {
  681. if (pow >= ANC_MAX_VOL_DIS_FB_DAC_THR) {
  682. change = 1;
  683. }
  684. }
  685. if (change) {
  686. anc_max_vol_change_cnt++;
  687. } else {
  688. anc_max_vol_change_cnt = 0;
  689. }
  690. if (anc_max_vol_change_cnt >= 25) {
  691. sta = (anc_max_vol_dac_vol_sta ? 0 : 1);
  692. }
  693. return sta;
  694. }
  695. AT(.com_text.anc.max_vol_dis_fb)
  696. void bsp_anc_max_vol_dis_fb_process(void)
  697. {
  698. u8 dac_vol_sta = 0;
  699. if ((anc_max_vol_process_sta) && (sys_cb.anc_user_mode) && (sys_cb.vol >= ANC_MAX_VOL_DIS_FB_VOL_THR)) {
  700. if (!tick_check_expire(anc_max_vol_dis_fb_tick, 20)) {
  701. return;
  702. }
  703. anc_max_vol_dis_fb_tick = tick_get();
  704. u32 pow = dac_pcm_pow_calc();
  705. dac_vol_sta = bsp_anc_max_vol_dac_det_process(pow);
  706. }
  707. if (dac_vol_sta != anc_max_vol_dac_vol_sta) {
  708. bsp_anc_max_vol_set_vol(dac_vol_sta);
  709. anc_max_vol_change_cnt = 0;
  710. }
  711. }
  712. void bsp_anc_max_vol_dac_det_start(void)
  713. {
  714. anc_max_vol_process_sta = 1;
  715. anc_max_vol_dac_vol_sta = 0;
  716. anc_max_vol_change_cnt = 0;
  717. }
  718. void bsp_anc_max_vol_dac_det_stop(void)
  719. {
  720. anc_max_vol_process_sta = 0;
  721. anc_max_vol_dac_vol_sta = 0;
  722. anc_max_vol_change_cnt = 0;
  723. }
  724. #endif // ANC_MAX_VOL_DIS_FB_EN
  725. #endif // ANC_EN
  726. #if TINY_TRANSPARENCY_EN
  727. void bsp_ttp_start(void)
  728. {
  729. if (sys_cb.ttp_start) return;
  730. audio_path_init(AUDIO_PATH_TTP);
  731. audio_path_start(AUDIO_PATH_TTP);
  732. sys_cb.ttp_start = 1;
  733. }
  734. void bsp_ttp_stop(void)
  735. {
  736. if (!sys_cb.ttp_start) return;
  737. sys_cb.ttp_start = 0;
  738. audio_path_exit(AUDIO_PATH_TTP);
  739. }
  740. //mode: 0[off], 1[off], 2[tansparency]
  741. void bsp_anc_set_mode(u8 mode)
  742. {
  743. sys_cb.anc_user_mode = mode;
  744. if (sys_cb.anc_user_mode == 2) {
  745. bsp_ttp_start();
  746. } else {
  747. bsp_ttp_stop();
  748. }
  749. TRACE("ttp user mode:%d\n", mode);
  750. }
  751. void bsp_ttp_init(void)
  752. {
  753. ttp_init(0);
  754. }
  755. void bsp_ttp_exit(void)
  756. {
  757. ttp_exit();
  758. }
  759. #endif
  760. #if ANC_ALG_AEM_RT_FF_FB_EN
  761. void bsp_anc_aem_set_fb_param(void)
  762. {
  763. u8 channel = 0;
  764. #if BT_TWS_EN
  765. if (xcfg_cb.bt_tws_en) {
  766. channel = !sys_cb.tws_left_channel;
  767. }
  768. #endif
  769. bsp_anc_set_nos_param_by_res(1, *anc_aem_fb_eq_tbl[2*channel+0].addr, *anc_aem_fb_eq_tbl[2*channel+0].len, 0, 0, 0);
  770. bsp_anc_set_msc_param_by_res(1, *anc_aem_fb_eq_tbl[2*channel+1].addr, *anc_aem_fb_eq_tbl[2*channel+1].len, 0, 0);
  771. anc_set_param();
  772. }
  773. void bsp_anc_aem_set_ff_param(u8 idx_num, u8 change_en)
  774. {
  775. u8 channel = 0;
  776. #if BT_TWS_EN
  777. if (xcfg_cb.bt_tws_en) {
  778. channel = !sys_cb.tws_left_channel;
  779. }
  780. #endif
  781. idx_num -= 1;
  782. bsp_anc_set_nos_param_by_res(0, *anc_aem_ff_eq_tbl[2*idx_num+channel].addr, *anc_aem_ff_eq_tbl[2*idx_num+channel].len, 0, 0, 0);
  783. anc_cfg.change_en = change_en;
  784. anc_set_param();
  785. anc_cfg.change_en = 0;
  786. }
  787. #endif