bsp_eq.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928
  1. #include "include.h"
  2. #include "bsp_eq.h"
  3. #include "bsp_anc.h"
  4. #if HLW_UI
  5. #include "hlw_func.h"
  6. #endif // HLW_UI
  7. #define TRACE_EN 0
  8. #if TRACE_EN
  9. #define TRACE(...) printf(__VA_ARGS__)
  10. #define TRACE_R(...) print_r(__VA_ARGS__)
  11. #else
  12. #define TRACE(...)
  13. #define TRACE_R(...)
  14. #endif // TRACE_EN
  15. #define EQ_CRC_SEED 0xffff
  16. #define EQ_BAND_NUM 12
  17. #define CAL_FIX(x) ((int)(x * (1 << 27)))
  18. u8 eq_rx_buf[EQ_BUFFER_LEN];
  19. #if EQ_DBG_IN_UART || EQ_DBG_IN_SPP
  20. eq_dbg_cb_t eq_dbg_cb;
  21. static u8 eq_tx_buf[12];
  22. const char tbl_eq_version[10] = {'E', 'Q', '1', '*', 6, 0, 12, 4, 5, 0};
  23. const char tbl_drc_version[10] = {'D', 'R', '0', '*', 6, 0, 4, 0, 0, 0};
  24. AT(.com_rodata.anc)
  25. const char tbl_anc_header[3] = "ANC";
  26. uint calc_crc(void *buf, uint len, uint seed);
  27. extern const eq_param music_eq_tbl[MUSIC_EQ_TBL_LEN];
  28. #if ONEMORE_SPATIAL_AU
  29. extern const eq_param music_space_eq_tbl[MUSIC_EQ_TBL_LEN];
  30. #endif // ONEMORE_SPATIAL_AU
  31. void music_set_pt_eq(u8 channel, u8 band_cnt, const u32 *param);
  32. void music_dbb_eq_index_init(u32* coef_l, u32* coef_r);
  33. typedef enum{
  34. EQ_RES,
  35. DRC_RES,
  36. }RES_TYPE_SET;
  37. u8 check_sum(u8 *buf, u16 size)
  38. {
  39. u32 i, sum = 0;
  40. for (i = 0; i < size; i++) {
  41. sum += buf[i];
  42. }
  43. return (u8)(-sum);
  44. }
  45. void tx_ack(uint8_t *packet, uint16_t len)
  46. {
  47. delay_5ms(1); //延时一段时间再ack
  48. if (eq_dbg_cb.rx_type) {
  49. #if EQ_DBG_IN_UART
  50. huart_tx(packet, len);
  51. #endif
  52. } else {
  53. #if EQ_DBG_IN_SPP && BT_SPP_EN
  54. if (xcfg_cb.eq_dgb_spp_en && (bt_get_status() >= BT_STA_CONNECTED)) {
  55. bt_spp_tx(SPP_SERVICE_CH0, packet, len);
  56. }
  57. #endif
  58. }
  59. eq_dbg_cb.rx_type = 0;
  60. }
  61. void eq_tx_ack(u8 bank_num, u8 ack, u8 type)
  62. {
  63. u8 ack_buf[4];
  64. if (type) {
  65. ack_buf[0] = 'D';
  66. } else {
  67. ack_buf[0] = 'A';
  68. }
  69. ack_buf[1] = bank_num;
  70. ack_buf[2] = ack;
  71. ack_buf[3] = check_sum(ack_buf, 3);
  72. // ack_buf[3] = -(ack_buf[0] + ack_buf[1] + ack_buf[2]);
  73. tx_ack(ack_buf, 4);
  74. }
  75. void eq_tx_version(u8 type)
  76. {
  77. if (type) {
  78. memcpy(eq_tx_buf, tbl_drc_version, 10);
  79. } else {
  80. memcpy(eq_tx_buf, tbl_eq_version, 10);
  81. }
  82. #if ANC_EN
  83. if (xcfg_cb.anc_en) {
  84. eq_tx_buf[9] |= BIT(0);
  85. }
  86. #endif
  87. u16 crc = calc_crc(eq_tx_buf, 10, EQ_CRC_SEED);
  88. eq_tx_buf[10] = crc;
  89. eq_tx_buf[11] = crc >> 8;
  90. tx_ack(eq_tx_buf, 12);
  91. }
  92. #if ANC_EQ_RES2_EN
  93. rmk_cb_t rmk_cb;
  94. u8 res2_eq_buf[MAX_RESBUF_SIZE] AT(.eq_rec_buf); //载入res2参数的缓存buf
  95. void eq_tx_setparam_res(u8 res)
  96. {
  97. eq_tx_buf[0] = 'E';
  98. eq_tx_buf[1] = 'Q';
  99. eq_tx_buf[2] = 'S';
  100. eq_tx_buf[3] = 'P';
  101. eq_tx_buf[4] = res;
  102. eq_tx_buf[5] = rmk_cb.err;
  103. tx_ack(eq_tx_buf, 6);
  104. }
  105. #endif
  106. #if ANC_EN
  107. #define FFFB_EQ_NAME_NUM 8
  108. static const char anc_fffb_eq_name[FFFB_EQ_NAME_NUM][13] = {
  109. "L0_NOS.EQ",
  110. "L0_MSC.EQ",
  111. "R0_NOS.EQ",
  112. "R0_MSC.EQ",
  113. "TP_L0_NOS.EQ",
  114. "TP_L0_MSC.EQ",
  115. "TP_R0_NOS.EQ",
  116. "TP_R0_MSC.EQ",
  117. };
  118. #define HYBRID_EQ_NAME_NUM 16
  119. static const char anc_hybrid_eq_name[HYBRID_EQ_NAME_NUM][13] = {
  120. "L0_NOS.EQ",
  121. "L0_MSC.EQ",
  122. "L1_NOS.EQ",
  123. "L1_MSC.EQ",
  124. "R0_NOS.EQ",
  125. "R0_MSC.EQ",
  126. "R1_NOS.EQ",
  127. "R1_MSC.EQ",
  128. "TP_L0_NOS.EQ",
  129. "TP_L0_MSC.EQ",
  130. "TP_L1_NOS.EQ",
  131. "TP_L1_MSC.EQ",
  132. "TP_R0_NOS.EQ",
  133. "TP_R0_MSC.EQ",
  134. "TP_R1_NOS.EQ",
  135. "TP_R1_MSC.EQ",
  136. };
  137. bool anc_eq_name_compare(const char *eq_name)
  138. {
  139. u32 i, num;
  140. const char (*anc_name)[13];
  141. if (xcfg_cb.anc_mode >= MODE_TWS_HYBRID) {
  142. num = HYBRID_EQ_NAME_NUM;
  143. anc_name = anc_hybrid_eq_name;
  144. } else {
  145. num = FFFB_EQ_NAME_NUM;
  146. anc_name = anc_fffb_eq_name;
  147. }
  148. eq_dbg_cb.anc_packet = 0;
  149. for (i = 0; i < num; i++) {
  150. if (strcmp(anc_name[i], eq_name) == 0) {
  151. eq_dbg_cb.anc_packet = i + 1;
  152. return true;
  153. }
  154. }
  155. TRACE("eq name fits nothing\n");
  156. return false;
  157. }
  158. #endif
  159. #if ANC_EN
  160. static bool bsp_eq_tws_sync_param(void)
  161. {
  162. #if BT_TWS_EN
  163. u8 channel, anc_packet = eq_dbg_cb.anc_packet - 1;
  164. if (xcfg_cb.anc_mode >= MODE_TWS_HYBRID) {
  165. channel = (anc_packet / 4) % 2; //右声道
  166. } else {
  167. channel = (anc_packet / 2) % 2;
  168. }
  169. if (xcfg_cb.bt_tws_en && (channel == sys_cb.tws_left_channel)) { //声道不相等,转发
  170. if(bt_tws_is_connected()) {
  171. bt_tws_sync_eq_param();
  172. }
  173. return true;
  174. }
  175. #endif
  176. return false;
  177. }
  178. #endif
  179. #if ANC_EQ_RES2_EN
  180. /*****************************************************************************
  181. * 功能 : 将flash中res2对应地址的4k字节内容,读取、放到*buf地址
  182. *****************************************************************************/
  183. void rmk_read_res2(u8 *buf)
  184. {
  185. u32 base_addr = FLASH_SIZE - 0x6000;
  186. os_spiflash_read(buf, base_addr, MAX_RESBUF_SIZE);
  187. }
  188. /*****************************************************************************
  189. * 功能 : 擦除*buf地址的长度为len字节的内容,然后初始化
  190. *****************************************************************************/
  191. void rmk_rec_res2(u8 *buf, u16 len)
  192. {
  193. u32 base_addr = FLASH_SIZE - 0x6000;
  194. os_spiflash_erase(base_addr);
  195. for (u16 i = 0; i < len; i += 256) {
  196. os_spiflash_program(buf + i, base_addr + i, 256);
  197. }
  198. // DEBUG
  199. // os_spiflash_read(res2_test_buf, base_addr, 128);
  200. // print_r(res2_test_buf, 128);
  201. }
  202. bool rmk_check_single_res_is_valid(u8 *entry)
  203. {
  204. u32 res_addr = GET_LE32(entry + 24);
  205. u32 res_len = GET_LE32(entry + 28);
  206. rmk_cb.err = 0;
  207. if (entry[0] == 0) {
  208. rmk_cb.err = RMK_ERR_RES_ENTRY_NAME;
  209. TRACE("RMK_ERR_RES_ENTRY_NAME");
  210. return false;
  211. }
  212. if (res_addr < RES_BASE || res_addr > RES_END) {
  213. rmk_cb.err = RMK_ERR_RES_ENTRY_ADDR;
  214. TRACE("RMK_ERR_RES_ENTRY_ADDR");
  215. return false;
  216. }
  217. if (res_len < 0 || res_len > MAX_RESBUF_SIZE || (res_addr + res_len) > RES_END) {
  218. rmk_cb.err = RMK_ERR_RES_ENTRY_LEN;
  219. TRACE("RMK_ERR_RES_ENTRY_LEN");
  220. return false;
  221. }
  222. return true;
  223. }
  224. /*****************************************************************************
  225. * 功能 : 将flash中res2对应地址的4k字节内容,读取、放到*res指向区域
  226. *****************************************************************************/
  227. bool rmk_init(u8 *res, u32 len)
  228. {
  229. u8 *resbuf = res;
  230. u32 i;
  231. u32 res_addr = 0;
  232. u32 res_len = 0;
  233. memset(&rmk_cb, 0, sizeof(rmk_cb_t));
  234. rmk_cb.len = len;
  235. if (len < 32 || len > MAX_RESBUF_SIZE) {
  236. rmk_cb.err = RMK_ERR_RES_LEN;
  237. TRACE("rmk_init RMK_ERR_RES_LEN\n");
  238. return false;
  239. }
  240. memcpy(resbuf, res, len);
  241. if (GET_LE32(resbuf) != 0xD2D4CEC5) { //ENTRY HEADER
  242. rmk_cb.err = RMK_ERR_RES_ENTRY_SIG;
  243. TRACE("RMK_ERR_RES_ENTRY_SIG");
  244. return false;
  245. }
  246. rmk_cb.rescnt = GET_LE32(resbuf + 28); //0x20
  247. for (i = 0; i < rmk_cb.rescnt; i++) {
  248. u8 *entry = resbuf + (i + 1) * 32;
  249. res_addr = GET_LE32(entry + 24);
  250. res_len = GET_LE32(entry + 28);
  251. if(!rmk_check_single_res_is_valid(entry)){
  252. return false;
  253. }
  254. }
  255. rmk_cb.res2len = res_addr + res_len - RES_BASE;
  256. return true;
  257. }
  258. /*********************************************************************************
  259. * 功能 : 若有res2参数,则存放到res2_eq_buf中;否则擦除、重新初始化4k flash段
  260. *********************************************************************************/
  261. void copy_res2flash(void)
  262. {
  263. TRACE("res2 copy res2flash\n");
  264. rmk_read_res2(res2_eq_buf);
  265. if (rmk_init(res2_eq_buf, MAX_RESBUF_SIZE)) {
  266. TRACE("reflash res2 4k flash\n");
  267. return;
  268. }
  269. memcpy(res2_eq_buf, (u8*)RES_BUF_RES2_BIN, RES_LEN_RES2_BIN);
  270. rmk_rec_res2(res2_eq_buf, RES_LEN_RES2_BIN);
  271. }
  272. /*********************************************************************************
  273. * 功能 : 将eq下载指令的参数,写入res2 对应flash的eq文件中
  274. *********************************************************************************/
  275. //将EQ文件整合入RES2文件
  276. bool rmk_set_eq(u8 *eqbuf)
  277. {
  278. TRACE("rmk_set_eq\n");
  279. rmk_cb.buf = res2_eq_buf;
  280. u8 *resbuf = rmk_cb.buf;
  281. int i;
  282. int eq_offest = 0;
  283. rmk_read_res2(resbuf);
  284. if (!(rmk_cb.eqlen && rmk_cb.res2len)) {
  285. return false;
  286. }
  287. for (i = rmk_cb.file_cnt; i < rmk_cb.rescnt; i++) {
  288. unsigned char *entry = resbuf + (i + 1) * 32;
  289. int res_addr = GET_LE32(entry + 24);
  290. int res_len = GET_LE32(entry + 28);
  291. if(!rmk_check_single_res_is_valid(entry)){
  292. return false;
  293. }
  294. if (i == rmk_cb.file_cnt) {
  295. u16 temp_len = rmk_cb.eqlen;
  296. u32 res_raddr = res_addr - RES_BASE;
  297. rmk_cb.eqlen = (u16)(rmk_cb.eqlen + 31)/32*32;//32byte对齐
  298. memset(eqbuf + temp_len, 0, rmk_cb.eqlen - temp_len);
  299. if (!bsp_anc_res_check_crc((u32)eqbuf, (u32)rmk_cb.eqlen)) {
  300. TRACE("rmk_cb.err RMK_ERR_RES_CRC_ERR\n");
  301. rmk_cb.err = RMK_ERR_RES_CRC_ERR;
  302. return false;
  303. }
  304. eq_offest = eq_offest + rmk_cb.eqlen - res_len;
  305. //如果填入的资源比原先的资源小,把资源前移
  306. if (eq_offest <= 0) {
  307. memcpy(resbuf + res_raddr + rmk_cb.eqlen, resbuf + res_raddr + res_len, rmk_cb.res2len - res_raddr - res_len);
  308. } else {
  309. //如果填入的资源比原先的资源多,把资源后移
  310. u32 copy_len =rmk_cb.res2len - (res_raddr + res_len);
  311. u16 j = rmk_cb.res2len + eq_offest-1;
  312. u16 k = rmk_cb.res2len - 1;
  313. for(u16 z = copy_len; z > 0; z-- ){
  314. resbuf[j--] = resbuf[k--];
  315. }
  316. }
  317. memcpy(resbuf + res_raddr, eqbuf, rmk_cb.eqlen);
  318. res_len = rmk_cb.eqlen;
  319. } else {
  320. res_addr += eq_offest;
  321. }
  322. PUT_LE32(entry + 24, res_addr);
  323. PUT_LE32(entry + 28, res_len);
  324. }
  325. #if TRACE_EN
  326. TRACE("\n\n\n");
  327. TRACE("res2 successfully keep data result:\n");
  328. print_r(resbuf, 4096);
  329. #endif // TRACE_EN
  330. rmk_rec_res2(resbuf, MAX_RESBUF_SIZE);
  331. rmk_cb.res2len = 0;
  332. rmk_cb.eqlen = 0;
  333. return true;
  334. }
  335. /*****************************************************************************************
  336. * 功能 : 收到产测指令EQSFM后,检查res2 4k flash内容是否正常,更新eqlen、file_cnt等参数
  337. *****************************************************************************************/
  338. bool rmk_save_file_param(u8 *buf)
  339. {
  340. rmk_cb.buf = res2_eq_buf;
  341. unsigned char *resbuf = rmk_cb.buf;
  342. int i;
  343. rmk_cb.eqlen = 0;
  344. rmk_cb.file_cnt = 0;
  345. rmk_read_res2(resbuf); //把res2对应flash内容读到resbuf中
  346. if(!rmk_init(resbuf, MAX_RESBUF_SIZE)){ //刷新4kflash是不是合法的,里面包含默认信息
  347. return false;
  348. }
  349. TRACE("rmk save file param rmk init succeddfully\n");
  350. for (i = 0; i < rmk_cb.rescnt; i++) {
  351. unsigned char *entry = resbuf + (i + 1) * 32;
  352. if (!rmk_check_single_res_is_valid(entry)) {
  353. return false;
  354. }
  355. if (!memcmp(buf, entry, 24)) { //字符串和默认信息匹配,确认eq文件序列数和包含滤波器字节数
  356. rmk_cb.eqlen = (u16)GET_LE32(buf + 24);
  357. rmk_cb.file_cnt = i;
  358. return true;
  359. }
  360. }
  361. return false;
  362. }
  363. #endif
  364. void bsp_eq_parse_cmd(void)
  365. {
  366. RES_TYPE_SET set_type = 0;
  367. #if TRACE_EN
  368. // print_r(eq_rx_buf, EQ_BUFFER_LEN);
  369. #endif
  370. if (eq_rx_buf[0] == 'E' && eq_rx_buf[1] == 'Q') {
  371. set_type = EQ_RES;
  372. } else if (eq_rx_buf[0] == 'D' && eq_rx_buf[1] == 'R') {
  373. set_type = DRC_RES;
  374. } else {
  375. return;
  376. }
  377. if (eq_rx_buf[2] == '?' && eq_rx_buf[3] == '#') {
  378. eq_tx_version(set_type);
  379. return;
  380. } else if (eq_rx_buf[2] == '0' && eq_rx_buf[3] == ':') {
  381. #if ANC_EN
  382. if (anc_eq_name_compare((const char *)&eq_rx_buf[6])) {
  383. if (!sys_cb.anc_start || sys_cb.anc_user_mode != 1) {
  384. bsp_anc_set_mode(1);
  385. }
  386. bsp_anc_fade_enable(0);
  387. bsp_eq_tws_sync_param();
  388. }
  389. #endif
  390. eq_tx_ack(0, 0, set_type);
  391. return;
  392. } else if (eq_rx_buf[2] == 'S' && (eq_rx_buf[3] == 'P' || eq_rx_buf[3] == 'F')) {
  393. #if ANC_EQ_RES2_EN
  394. u8 res = 1;
  395. bt_audio_bypass();
  396. if ((eq_rx_buf[5] == 'E') && (eq_rx_buf[6] == 'q')) {
  397. res = rmk_set_eq(eq_rx_buf + 5) ? 0 : 1;
  398. } else if ((eq_rx_buf[5] == 'F') && (eq_rx_buf[6] == 'M')) {
  399. res = rmk_save_file_param(eq_rx_buf + 7) ? 0 : 1;
  400. }
  401. bt_audio_enable();
  402. if (!eq_rx_buf[4] && (!res)) {
  403. eq_rx_buf[4] = 1;
  404. bt_tws_sync_eq_param();
  405. }
  406. eq_tx_setparam_res(res);
  407. #endif
  408. return ;
  409. } else if (eq_rx_buf[2] == 'S' && (eq_rx_buf[3] == 'M')) {
  410. #if ANC_EQ_RES2_EN
  411. u8 mode = eq_rx_buf[8];
  412. rmk_cb.err = 0;
  413. if (mode > 2) {
  414. eq_tx_setparam_res(1);
  415. return;
  416. }
  417. sys_cb.anc_user_mode = mode;
  418. bsp_anc_set_mode(sys_cb.anc_user_mode);
  419. if (!eq_rx_buf[4]) {
  420. eq_rx_buf[4] = 1;
  421. bt_tws_sync_eq_param();
  422. }
  423. eq_tx_setparam_res(0);
  424. return;
  425. #endif
  426. #if DAC_PT_EN
  427. } else if (eq_rx_buf[2] == 'S' && (eq_rx_buf[3] == 'D') && (eq_rx_buf[4] == 'A') && (eq_rx_buf[5] == 'C')) {
  428. u8 band_num = eq_rx_buf[7]; //eq 滤波器数量
  429. u8 channel = eq_rx_buf[8]; //左右声道标志位:1->左声道;2->右声道;3->验双声道效果
  430. u32 crc_rx = calc_crc(eq_rx_buf, (9 + band_num*4*5), EQ_CRC_SEED);
  431. TRACE("dac pt rx_buf, band_num [%d], ch [%d], crc [%4x]\n", band_num, channel, crc_rx);
  432. if (crc_rx == little_endian_read_16(eq_rx_buf, (9 + band_num*4*5))) { //crc16校验
  433. eq_tx_ack(band_num, 1, set_type); //校验成功,发送ack1
  434. TRACE("dac pt rx_buf crc check successfully\n");
  435. } else {
  436. eq_tx_ack(band_num, 0, set_type); //校验失败,发送ack0
  437. TRACE("dac pt rx_buf crc err, correct code :%4x\n", little_endian_read_16(eq_rx_buf, (12 + band_num*4*5)));
  438. return;
  439. }
  440. if (eq_rx_buf[6] == 'T') { //设置eq参数听效果
  441. if (channel == 1 || channel == 2) {
  442. eq_tx_ack(band_num, channel, set_type);
  443. TRACE("dac pt SDACT cmd ch check successfully\n");
  444. } else {
  445. eq_tx_ack(band_num, 0, set_type);
  446. TRACE("dac pt SDACT cmd ch check err, %d\n", channel);
  447. return;
  448. }
  449. music_set_pt_eq(channel-1, band_num, (u32 *)&eq_rx_buf[9]);
  450. } else if (eq_rx_buf[6] == 'R') { //烧录eq参数
  451. u8 error_code = 0;
  452. if (channel == 1 || channel == 2) {
  453. u8 dac_ch = channel - 1;
  454. cm_write8(PARAM_DAC_PT_NUM + dac_ch, band_num);
  455. cm_write(&eq_rx_buf[9], DAC_PT_PAGE(dac_ch * 120), band_num * 4 * 5);
  456. cm_sync();
  457. error_code = channel;
  458. TRACE("dac pt SDACR cmd cm_write successfully\n");
  459. } else if (channel == 3) {
  460. plugin_music_eq();
  461. error_code = channel;
  462. TRACE("dac pt SDACR cmd plugin_music_eq\n");
  463. } else {
  464. error_code = 4;
  465. TRACE("dac pt SDACR cmd err\n");
  466. }
  467. eq_tx_ack(band_num, error_code, set_type);
  468. }
  469. return;
  470. #endif
  471. }
  472. u8 band_num = eq_rx_buf[6];
  473. u32 size = little_endian_read_16(eq_rx_buf, 4);
  474. u32 crc = calc_crc(eq_rx_buf, size+4, EQ_CRC_SEED);
  475. #if ANC_EN
  476. if (eq_dbg_cb.anc_packet && bsp_eq_tws_sync_param()) {
  477. delay_5ms(20); //wait tws send complete
  478. eq_tx_ack(band_num, 0, set_type);
  479. return;
  480. }
  481. #endif
  482. if (crc == little_endian_read_16(eq_rx_buf, 4+size)) {
  483. eq_tx_ack(band_num, 0, set_type);
  484. } else {
  485. eq_tx_ack(band_num, 1, set_type);
  486. return;
  487. }
  488. u8 band_cnt = eq_rx_buf[7];
  489. #if ANC_EN
  490. if (eq_dbg_cb.anc_packet) {
  491. bsp_anc_dbg_eq_param(eq_dbg_cb.anc_packet, band_cnt, (u32 *)&eq_rx_buf[14]);
  492. } else
  493. #endif
  494. {
  495. if (set_type) {
  496. // music_set_drc(band_cnt, (u32 *)&eq_rx_buf[10]);
  497. } else {
  498. #if BT_TWS_EN
  499. if (!bt_tws_is_slave()) {
  500. eq_rx_buf[0] = 'E';
  501. eq_rx_buf[1] = 'Q';
  502. bt_tws_sync_eq_param();
  503. }
  504. #endif
  505. music_set_eq(band_cnt, (u32 *)&eq_rx_buf[14]);
  506. }
  507. }
  508. #if (UART0_PRINTF_SEL != PRINTF_NONE)
  509. u8 k;
  510. u32 *ptr = (u32 *)&eq_rx_buf[10];
  511. if (set_type) {
  512. for (k = 0; k < 10; k++) {
  513. printf("%08x", *ptr++);
  514. if (k % 5 == 4) {
  515. printf("\n");
  516. } else {
  517. printf(" ");
  518. }
  519. }
  520. } else {
  521. printf("%08x\n", little_endian_read_32(eq_rx_buf, 14));
  522. ptr = (u32 *)&eq_rx_buf[18];
  523. for (k = 0; k < band_cnt*5; k++) {
  524. printf("%08x", *ptr++);
  525. if (k % 5 == 4) {
  526. printf("\n");
  527. } else {
  528. printf(" ");
  529. }
  530. }
  531. }
  532. #endif
  533. memset(eq_rx_buf, 0, EQ_BUFFER_LEN);
  534. }
  535. #if BT_TWS_EN
  536. uint16_t tws_get_spp_eq_info(uint8_t *buf)
  537. {
  538. if (buf != NULL) {
  539. memcpy(buf, eq_rx_buf, EQ_BUFFER_LEN);
  540. }
  541. // printf("get_spp_eq: %d\n", EQ_BUFFER_LEN);
  542. return EQ_BUFFER_LEN;
  543. }
  544. void tws_set_spp_eq_info(uint8_t *buf, uint16_t len)
  545. {
  546. if (buf != NULL) {
  547. memcpy(eq_rx_buf, buf, len);
  548. if (memcmp(eq_rx_buf, tbl_anc_header, 3) == 0) {
  549. msg_enqueue(EVT_ONLINE_SET_ANC);
  550. } else {
  551. msg_enqueue(EVT_ONLINE_SET_EQ);
  552. }
  553. }
  554. // printf("set_spp_eq: %d\n", len);
  555. }
  556. #endif
  557. AT(.com_huart.text)
  558. u8 bsp_eq_rx_done(u8* rx_buf)
  559. {
  560. if (memcmp(rx_buf, tbl_anc_header, 3) == 0) {
  561. msg_enqueue(EVT_ONLINE_SET_ANC);
  562. eq_dbg_cb.rx_type = 1;
  563. } else if(((rx_buf[0]=='E')&&(rx_buf[1]=='Q')) || (rx_buf[0] == 'D' && rx_buf[1] == 'R')){
  564. msg_enqueue(EVT_ONLINE_SET_EQ);
  565. eq_dbg_cb.rx_type = 1;
  566. }
  567. #if BT_MUSIC_EFFECT_DBG_EN
  568. else if ((rx_buf[0]=='C')&&(rx_buf[1]=='A')&&(rx_buf[2]=='R')&&(rx_buf[3]=='_')) {
  569. msg_enqueue(EVT_ONLINE_SET_EFFECT);
  570. eq_dbg_cb.rx_type = 1;
  571. }
  572. #endif
  573. return eq_dbg_cb.rx_type;
  574. }
  575. void eq_dbg_init(void)
  576. {
  577. memset(&eq_dbg_cb, 0, sizeof(eq_dbg_cb_t));
  578. }
  579. #endif
  580. AT(.text.music)
  581. void music_set_eq_by_num(u8 num)
  582. {
  583. if (num > (MUSIC_EQ_TBL_LEN - 1)) {
  584. return;
  585. }
  586. #if EQ_APP_EN
  587. eq_msc_index_init(0);
  588. #endif
  589. #if BT_MUSIC_EFFECT_SPATIAL_AU_EN && BT_MUSIC_EFFECT_SPATIAL_AUEQ_EN
  590. if (music_spatial_audio_get_fix_eq_sta()) {
  591. music_set_eq_by_res(RES_BUF_EQ_SPATIAL_AUDIO_EQ, RES_LEN_EQ_SPATIAL_AUDIO_EQ);
  592. return;
  593. }
  594. #endif
  595. #if BT_MUSIC_EFFECT_HRTF_RT_EN && BT_MUSIC_EFFECT_HRTF_RT_EQ_EN
  596. if (music_hrtf_rt_get_fix_eq_sta()) {
  597. music_set_eq_by_res(RES_BUF_EQ_SPATIAL_AUDIO_EQ, RES_LEN_EQ_SPATIAL_AUDIO_EQ);
  598. return;
  599. }
  600. #endif
  601. music_set_eq_by_res(*music_eq_tbl[num].addr, *music_eq_tbl[num].len);
  602. }
  603. #if ONEMORE_SPATIAL_AU
  604. AT(.text.music)
  605. void music_space_set_eq_by_num(u8 num)
  606. {
  607. printf("music_set_eq_by_num num %d\n", num);
  608. if (num > (MUSIC_EQ_TBL_LEN - 1)) {
  609. return;
  610. }
  611. #if EQ_APP_EN
  612. eq_msc_index_init(0);
  613. #endif
  614. #if BT_MUSIC_EFFECT_SPATIAL_AU_EN && BT_MUSIC_EFFECT_SPATIAL_AUEQ_EN
  615. if (music_spatial_audio_get_fix_eq_sta()) {
  616. music_set_eq_by_res(RES_BUF_EQ_SPATIAL_AUDIO_EQ, RES_LEN_EQ_SPATIAL_AUDIO_EQ);
  617. return;
  618. }
  619. #endif
  620. #if BT_MUSIC_EFFECT_HRTF_RT_EN && BT_MUSIC_EFFECT_HRTF_RT_EQ_EN
  621. if (music_hrtf_rt_get_fix_eq_sta()) {
  622. music_set_eq_by_res(RES_BUF_EQ_SPATIAL_AUDIO_EQ, RES_LEN_EQ_SPATIAL_AUDIO_EQ);
  623. return;
  624. }
  625. #endif
  626. music_set_eq_by_res(*music_space_eq_tbl[num].addr, *music_space_eq_tbl[num].len);
  627. }
  628. #endif // ONEMORE_SPATIAL_AU
  629. #if EQ_MODE_EN
  630. AT(.text.music)
  631. void sys_set_eq(void)
  632. {
  633. sys_cb.eq_mode++;
  634. #if HLW_UI
  635. if (sys_cb.eq_mode > (MUSIC_EQ_TBL_LEN - 1)) {
  636. #else
  637. if (sys_cb.eq_mode > 5) {
  638. #endif // HLW_UI
  639. sys_cb.eq_mode = 0;
  640. }
  641. music_set_eq_by_num(sys_cb.eq_mode);
  642. gui_box_show_eq();
  643. }
  644. #endif // EQ_MODE_EN
  645. struct eq_coef_t {
  646. u32 param0; //频点参数,由工具计算
  647. u32 param1;
  648. u32 *coef; //频段参数,由eq_coef_cal计算
  649. };
  650. #if EQ_APP_EN || DAC_PT_EN || BT_MUSIC_EFFECT_DBB_EN
  651. struct eq_div_t {
  652. uint32_t total_gain;
  653. u32 coef[DAC_EQ_NUM_TOTAL][5]; //顺序:APP、产测、动态低音
  654. };
  655. #if EQ_APP_EN
  656. static struct eq_coef_t app_coef[EQ_APP_NUM]; //存放每条计算的参数(APP不分左右声道)
  657. #endif
  658. #if ANC_ALG_ADP_EQ_FF_FB_EN
  659. static struct eq_coef_t adp_eq_coef;
  660. int get_anc_alg_adp_eq_coef(u8 idx);
  661. #endif
  662. static struct eq_div_t eq_div[2]; //存放所有div eq的参数(左右声道)
  663. //根据index设置12条EQ示例,包含高低音
  664. //Q:0.750000
  665. #if ONEMORE_APP_EN
  666. //代码10个点:gain 1 0 0 0 0 -1 3.8 0 0 -2
  667. //代码10个点: 68 0.5 282 0.6 682 0.8 1234 0.9 2013 1 3080 1.4 4800 1.5 6794 2 9815 2.2 13236 2
  668. static const int tbl_coef[EQ_APP_NUM][2] = {
  669. //param0 param1
  670. { CAL_FIX(0.0044505750), CAL_FIX(0.9999900961)},
  671. { CAL_FIX(0.0188484402), CAL_FIX(0.9998223524)},
  672. { CAL_FIX(0.0371849797), CAL_FIX(0.9990039436)},
  673. { CAL_FIX(0.0580713701), CAL_FIX(0.9945218951)},
  674. { CAL_FIX(0.0362572766), CAL_FIX(0.9914448609)},
  675. { CAL_FIX(0.0360779554), CAL_FIX(0.9729777445)},
  676. { CAL_FIX(0.1030056676), CAL_FIX(0.9510565136)},
  677. { CAL_FIX(0.0776024220), CAL_FIX(0.8849876312)},
  678. { CAL_FIX(0.0571787974), CAL_FIX(0.8204014338)},
  679. { CAL_FIX(0.1904835237), CAL_FIX(0.6476545645)},
  680. };
  681. #else
  682. static const int tbl_coef[12][2] = {
  683. //param0 param1
  684. { CAL_FIX(0.0029444916), CAL_FIX(0.9999902462)}, //Band:0(31Hz)
  685. { CAL_FIX(0.0059839058), CAL_FIX(0.9999597162)}, //Band:1(63Hz)
  686. { CAL_FIX(0.0151961090), CAL_FIX(0.9997401793)}, //Band:2(160Hz)
  687. { CAL_FIX(0.0237409561), CAL_FIX(0.9993657117)}, //Band:3(250Hz)
  688. { CAL_FIX(0.0379729998), CAL_FIX(0.9983764898)}, //Band:4(400Hz)
  689. { CAL_FIX(0.0946628813), CAL_FIX(0.9898674722)}, //Band:5(1000Hz)
  690. { CAL_FIX(0.1874074140), CAL_FIX(0.9596752251)}, //Band:6(2000Hz)
  691. { CAL_FIX(0.3597005044), CAL_FIX(0.8419530754)}, //Band:7(4000Hz)
  692. { CAL_FIX(0.6057018917), CAL_FIX(0.4177699622)}, //Band:8(8000Hz)
  693. { CAL_FIX(0.5060881129), CAL_FIX(-0.6509365173)}, //Band:9(16000Hz)
  694. { CAL_FIX(0.0284864965), CAL_FIX(0.9990866674)}, //BASS:300Hz
  695. { CAL_FIX(0.2763541250), CAL_FIX(0.9100351062)}, //TREB:3000Hz
  696. };
  697. #endif // ONEMORE_APP_EN
  698. void eq_index_init(void)
  699. {
  700. eq_div[0].total_gain = 0x800000;
  701. eq_div[1].total_gain = 0x800000;
  702. #if EQ_APP_EN
  703. for (int i = 0; i < EQ_APP_NUM; i++) {
  704. app_coef[i].param0 = tbl_coef[i][0];
  705. app_coef[i].param1 = tbl_coef[i][1];
  706. app_coef[i].coef = eq_div[0].coef[i]; //只配置左声道
  707. }
  708. #endif
  709. music_eq_divband_init(0, DAC_EQ_NUM_TOTAL, (u32 *)eq_div[0].coef); //DACL
  710. music_eq_divband_init(1, DAC_EQ_NUM_TOTAL, (u32 *)eq_div[1].coef); //DACR
  711. #if DAC_PT_EN
  712. for (int i = 0; i < 2; i++) {
  713. u8 dac_pt_num = cm_read8(PARAM_DAC_PT_NUM + i);
  714. if (dac_pt_num != 0) {
  715. cm_read(&(eq_div[i].coef[EQ_APP_NUM][0]), DAC_PT_PAGE(120 * i), dac_pt_num * 5 * 4);
  716. TRACE("dac pt cm_read param do\n");
  717. }
  718. }
  719. #endif
  720. #if BT_MUSIC_EFFECT_DBB_EN
  721. music_dbb_eq_index_init(&(eq_div[0].coef[EQ_APP_NUM+DAC_PT_NUM][0]), &(eq_div[1].coef[EQ_APP_NUM+DAC_PT_NUM][0]));
  722. #endif // BT_MUSIC_EFFECT_DBB_EN
  723. #if ANC_ALG_ADP_EQ_FF_FB_EN
  724. adp_eq_coef.param0 = get_anc_alg_adp_eq_coef(0);
  725. adp_eq_coef.param1 = get_anc_alg_adp_eq_coef(1);
  726. adp_eq_coef.coef = eq_div[0].coef[EQ_APP_NUM+DAC_PT_NUM+BT_MUSIC_EFFECT_DBB_BAND_CNT];
  727. #endif // ANC_ALG_ADP_EQ_FF_FB_EN
  728. }
  729. void eq_msc_index_init(u8 flag)
  730. {
  731. #if ONEMORE_APP_EN
  732. if (hlw_cb.eq_init_flag == flag)
  733. {
  734. my_printf("eq_msc_index_init return\n");
  735. return;
  736. }
  737. else
  738. {
  739. hlw_cb.eq_init_flag = flag;
  740. my_printf("eq_msc_index_init index_eq_flag --> %d\n", flag);
  741. }
  742. int i;
  743. for (i = 0; i < EQ_APP_NUM; i++)
  744. {
  745. if (flag)
  746. {
  747. my_printf("eq_msc_index_init %d\n", i);
  748. app_coef[i].param0 = tbl_coef[i][0];
  749. app_coef[i].param1 = tbl_coef[i][1];
  750. app_coef[i].coef = eq_div[0].coef[i];
  751. music_eq_divband_init(0, DAC_EQ_NUM_TOTAL, (u32 *)eq_div[0].coef); //DACL
  752. music_eq_divband_init(1, DAC_EQ_NUM_TOTAL, (u32 *)eq_div[1].coef); //DACR
  753. }
  754. else
  755. {
  756. music_eq_divband_init(0, 0, (u32 *)eq_div[0].coef); //DACL
  757. music_eq_divband_init(1, 0, (u32 *)eq_div[1].coef); //DACR
  758. }
  759. }
  760. #endif // ONEMORE_APP_EN
  761. }
  762. #if DAC_PT_EN
  763. //设置产测EQ
  764. void music_set_pt_eq(u8 channel, u8 band_cnt, const u32 *param)
  765. {
  766. if (band_cnt > DAC_PT_NUM || band_cnt == 0 || param == NULL) {
  767. TRACE("dac pt SDADT music_set_pt_eq err, band_cnt %d\n", band_cnt);
  768. return;
  769. }
  770. memcpy(&(eq_div[channel].coef[EQ_APP_NUM][0]), param, band_cnt * 5 * 4);
  771. TRACE("dac pt SDADT music_set_pt_eq, ch %d, band_cnt %d\n", channel, band_cnt);
  772. music_set_eq_by_num(sys_cb.eq_mode);
  773. }
  774. #endif
  775. #if EQ_APP_EN
  776. //根据EQ号来设置EQ[11:0]
  777. void music_set_eq_for_index(u8 index, int gain)
  778. {
  779. if (index >= EQ_APP_NUM || gain < -12 || gain > 12) {
  780. return;
  781. }
  782. printf("%s index:%d gain:%d\n", __func__, index,gain);
  783. #if ONEMORE_APP_EN
  784. eq_msc_index_init(1);
  785. my_printf("music_set_eq_for_index index %d, gain %d\n", index, gain);
  786. eq_coef_cal(&app_coef[index], gain);
  787. memcpy(eq_div[1].coef[index], eq_div[0].coef[index], 20); //左右声道保持一致
  788. #else
  789. eq_coef_cal(&app_coef[index], gain);
  790. memcpy(eq_div[1].coef[index], eq_div[0].coef[index], 20); //左右声道保持一致
  791. #endif // ONEMORE_APP_EN
  792. }
  793. void music_set_eq_for_index_do(void)
  794. {
  795. #if ONEMORE_APP_EN
  796. music_set_eq_by_res(RES_BUF_EQ_CUSTOM_EQ, RES_LEN_EQ_CUSTOM_EQ);
  797. #else
  798. music_set_eq_by_num(sys_cb.eq_mode);
  799. #endif // ONEMORE_APP_EN
  800. }
  801. #if ONEMORE_APP_EN
  802. void music_space_set_eq_for_index_do(void)
  803. {
  804. music_set_eq_by_res(RES_BUF_EQ_SP_CUSTOM_EQ, RES_LEN_EQ_SP_CUSTOM_EQ);
  805. }
  806. #endif // ONEMORE_APP_EN
  807. static const uint32_t eq_total_gain_tbl[14] = {
  808. 0x287a27, 0x2d6a86, 0x32f52d, 0x392cee, 0x4026e7, 0x47facd, 0x50c336, 0x5a9df8,
  809. 0x65ac8c, 0x721483, 0x800000, 0x8f9e4d, 0xa12478, 0xb4ce08,
  810. };
  811. //设置EQ总增益
  812. void music_set_eq_overall_gain(int gain)
  813. {
  814. if (gain > 3 || gain < -10) {
  815. return;
  816. }
  817. eq_div[1].total_gain = eq_div[0].total_gain = eq_total_gain_tbl[gain+10];
  818. }
  819. #endif
  820. #if ANC_ALG_ADP_EQ_FF_FB_EN
  821. void anc_adp_eq_set_gain(int gain, int gain_fraction)
  822. {
  823. u8 index = EQ_APP_NUM+DAC_PT_NUM+BT_MUSIC_EFFECT_DBB_BAND_CNT;
  824. if (gain < 0 || gain > 24) {
  825. return;
  826. }
  827. // printf("gain:%d.%d\n", gain, gain_fraction);
  828. bass_treble_coef_cal_ext(&adp_eq_coef, gain, gain_fraction, 0);
  829. memcpy(eq_div[1].coef[index], eq_div[0].coef[index], 20); //左右声道保持一致
  830. music_set_eq_by_num(sys_cb.eq_mode);
  831. }
  832. #endif // ANC_ALG_ADP_EQ_FF_FB_EN
  833. #endif
  834. void music_get_eq_total_gain(u32* gain)
  835. {
  836. #if !ONEMORE_APP_EN
  837. #if EQ_APP_EN
  838. if (sys_cb.eq_app_total_gain_en) {
  839. *gain = eq_div[0].total_gain;
  840. }
  841. #endif // EQ_APP_EN
  842. #if BT_MUSIC_EFFECT_EN
  843. music_effect_get_music_eq_total_gain(gain);
  844. #endif // BT_MUSIC_EFFECT_EN
  845. #endif // ONEMORE_APP_EN
  846. }
  847. void bsp_eq_init(void)
  848. {
  849. eq_var_init();
  850. #if EQ_APP_EN || DAC_PT_EN || BT_MUSIC_EFFECT_DBB_EN || ANC_ALG_ADP_EQ_FF_FB_EN
  851. eq_index_init();
  852. #endif
  853. }