bsp_iis.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653
  1. #include "include.h"
  2. #if IIS_EN
  3. #define IIS_TEST_DEMO 1
  4. #define TRACE_EN 0
  5. #if TRACE_EN
  6. #define TRACE(...) printf(__VA_ARGS__)
  7. #else
  8. #define TRACE(...)
  9. #endif
  10. iis_cfg_t *iis_libcfg;
  11. ///计算IIS模块时钟分频比的方法
  12. //计算方法:mclk = 参考时钟/(mdiv+1) //这里的参考时钟即PLL1DIV
  13. // bclk = mclk/(bdiv+1)(不能1分频)
  14. // lrclk = 采样率 = bclk/(位数*2)
  15. //fs实际上是指 MCLK/LRC // MCLK = fs * LRC
  16. //IISBAUD[6:0] mclk_div
  17. //IISBAUD[11:7] bclk_div
  18. //IIS时钟源默认和DAC是一样的,更改IIS采样率(IIS_LRC)需要参考当前DAC的采样率DAC_OUT_SPR (设置为44.1K或48K)
  19. //16 BIT时钟分频配置
  20. //LRC为44.1K时:
  21. //16bit: BCLK = 44.1K*32 = 1.4112M
  22. //64fs: 44.1K * 32 *2 (bdiv) = 2.8224M = MCLK //(MCLK * mdiv_8) = 22.5792M
  23. //128fs: 44.1K * 32 *4(bdiv) = 5.644.8M = MCLK //(MCLK * mdiv_4) = 22.5792M
  24. //256fs: 44.1K * 32 *8 (bdiv) = 11. 2896M = MCLK //(MCLK * mdiv_2) = 22.5792M
  25. //LRC为48K时:
  26. //16bit: BCLK = 48K*32 = 1.536M
  27. //64fs: 48K * 32 *2 (bdiv) = 3.072M = MCLK //(MCLK * mdiv_8) = 24.576M
  28. //128fs: 48K * 32 *4 (bdiv) = 6.144M = MCLK //(MCLK * mdiv_4) = 24.576M
  29. //256fs: 48K * 32 *8 (bdiv) = 12.288M = MCLK //(MCLK * mdiv_2) = 24.576M
  30. u8 i2s_16bit_clk_div[3][2] = {
  31. //bclkdiv ////mclk_div
  32. {2-1, 8-1}, //64fs
  33. {4-1, 4-1}, //128fs
  34. {8-1, 6-1}, //16k, no 256fs for 48k,
  35. };
  36. //32 BIT时钟分频配置
  37. //LRC为44.1K时:
  38. //32bit: BCLK = 44.1K*32 = 2.8224M
  39. //64fs: 44.1K * 64 *8 (bdiv) = 22.5792M = MCLK //(MCLK * mdiv_1) = 22.5792M
  40. //128fs: 44.1K * 64 *2 (bdiv) = 5.644.8M = MCLK //(MCLK * mdiv_4) = 22.5792M
  41. //256fs: 44.1K * 64 *4 (bdiv) = 11.289.6M = MCLK //(MCLK * mdiv_2) = 22.5792M
  42. //LRC为48K时:
  43. //32bit: BCLK = 48K * 64 = 3.072M
  44. //64fs: 48K * 64 *8 (bdiv) = 24.576M = MCLK //(MCLK * mdiv_1) = 24.576M
  45. //128fs: 48K * 64 *2 (bdiv) = 6.144M = MCLK //(MCLK * mdiv_1) = 24.576M
  46. //256fs: 48K * 64 *4 (bdiv) = 12.288M = MCLK //(MCLK * mdiv_1) = 24.576M
  47. u8 i2s_32bit_clk_div[3][2] = {
  48. //bclkdiv //mclk_div
  49. {8-1,1-1}, //64fs
  50. {2-1,4-1}, //128fs
  51. {4-1,2-1}, //256fs
  52. };
  53. ///--------------------------------------------------------
  54. #if TRACE_EN
  55. AT(.com_text.iis_cst)
  56. const char str_iistx_info[] = "IISTX: master = %d, samples = %d, isrcnt = %d (SR_%d)\n";
  57. const IIS_MODE_INFO_TBL iis_mode_info_tbl[10] = {
  58. {IIS_MASTER_SRCTX, "IIS_MASTER_SRCTX",},
  59. {IIS_MASTER_RAMTX, "IIS_MASTER_RAMTX",},
  60. {IIS_MASTER_RAMTX_RAMRX, "IIS_MASTER_RAMTX_RAMRX",},
  61. {IIS_MASTER_SRCTX_RAMRX, "IIS_MASTER_SRCTX_RAMRX",},
  62. {IIS_MASTER_RAMRX, "IIS_MASTER_RAMRX",},
  63. {IIS_MASTER_RAMRX_ONEWIRE, "IIS_MASTER_RAMRX_ONEWIRE"},
  64. {IIS_SLAVE_RAMRX, "IIS_SLAVE_RAMRX",},
  65. {IIS_SLAVE_RAMRX_ONEWIRE, "IIS_SLAVE_RAMRX_ONEWIRE",},
  66. {IIS_SLAVE_RAMTX, "IIS_SLAVE_RAMTX",},
  67. {IIS_SLAVE_RAMTX_RAMRX, "IIS_SLAVE_RAMTX_RAMRX",},
  68. };
  69. void iis_mode_info_print(void)
  70. {
  71. for (int i = 0; i < 10; i++) {
  72. if (iis_mode_info_tbl[i].iis_mode == iis_libcfg->mode) {
  73. TRACE("iis_mode[0x%X] = %s\n", iis_libcfg->mode, iis_mode_info_tbl[i].iis_str_info);
  74. break;
  75. }
  76. }
  77. }
  78. void iis_sfr_info_dump(void)
  79. {
  80. TRACE("\ndump iis sfr info:\n");
  81. TRACE("IISCON0 = 0x%X\n",IISCON0);
  82. TRACE("IISBAUD = 0x%X, IISDMACNT = 0x%X_%d\n", IISBAUD, IISDMACNT, IISDMACNT);
  83. TRACE("IISDMAOADR0 = 0x%X, IISDMAOADR1 = 0x%X\n", IISDMAOADR0, IISDMAOADR1);
  84. TRACE("IISDMAIADR0 = 0x%X, IISDMAIADR1 = 0x%X\n", IISDMAIADR0, IISDMAIADR1);
  85. TRACE("DACDIGCON = 0x%X\n", DACDIGCON0);
  86. if(iis_libcfg) {
  87. TRACE("iis_dma_buf : 0x%X\n", iis_libcfg->dma_cfg.dmabuf_ptr);
  88. }
  89. }
  90. #endif
  91. u8 iis_io_init(TYPE_IIS_IO io_map, TYPE_IIS_MODE iis_mode, TYPE_MCLK_OUT_SEL mclk_out_en)
  92. {
  93. TRACE("%s: ",__func__);
  94. FUNCMCON2 = 0x0F;
  95. if (IIS_G1 == io_map) {
  96. TRACE("IIS_G1, MCLK_PA4, BCLK_PA5, LRC_PA6, DO_PA7, DI_PB3\n");
  97. FUNCMCON2 |= 0x01;
  98. if (iis_mode & IISCFG_MASTER) { //MASTER,BCLK,LRC,MCLK out
  99. TRACE("MASTER ");
  100. GPIOAFEN |= (BIT(5) | BIT(6));
  101. GPIOADE |= (BIT(5) | BIT(6));
  102. GPIOADIR &= ~(BIT(5) | BIT(6));
  103. if (mclk_out_en) {
  104. TRACE("MCLK_OUT_EN ");
  105. GPIOAFEN |= BIT(4);
  106. GPIOADE |= BIT(4);
  107. GPIOADIR &= ~ BIT(4);
  108. } else {
  109. TRACE("MCLK_OUT_DIS ");
  110. }
  111. } else { //SLAVE: BCLK,LRC in
  112. TRACE("SLAVE ");
  113. GPIOAFEN |= (BIT(5) | BIT(6));
  114. GPIOADE |= (BIT(5) | BIT(6));
  115. GPIOADIR |= (BIT(5) | BIT(6));
  116. GPIOAPU |= (BIT(5) | BIT(6));
  117. }
  118. if (iis_mode & IISCFG_TX) { //DO out
  119. TRACE("TX_DO_OUT ");
  120. GPIOAFEN |= BIT(7);
  121. GPIOADE |= BIT(7);
  122. GPIOADIR &= ~BIT(7);
  123. }
  124. if (iis_mode & IISCFG_RX) { //DI in
  125. TRACE("RX_DI_IN ");
  126. if (iis_mode & IISCFG_ONEWIRE)//单线模式
  127. {
  128. TRACE("iis one wire io");
  129. GPIOAFEN |= BIT(7);
  130. GPIOADE |= BIT(7);
  131. GPIOADIR |= BIT(7);
  132. GPIOAPU |= BIT(7);
  133. } else {
  134. GPIOBFEN |= BIT(3);
  135. GPIOBDE |= BIT(3);
  136. GPIOBDIR |= BIT(3);
  137. GPIOBPU |= BIT(3);
  138. }
  139. }
  140. } else if (IIS_G2 == io_map) {
  141. TRACE("IIS_G2, MCLK_PE4, BCLK_PE5, LRC_PE6, DO_PE7, DI_PE0\n");
  142. FUNCMCON2 |= 0x02;
  143. if (iis_mode & IISCFG_MASTER) { //MASTER,BCLK,LRC,MCLK out
  144. TRACE("MASTER ");
  145. GPIOEFEN |= (BIT(5) | BIT(6));
  146. GPIOEDE |= (BIT(5) | BIT(6));
  147. GPIOEDIR &= ~(BIT(5) | BIT(6));
  148. if (mclk_out_en) {
  149. TRACE("MCLK_OUT_EN ");
  150. GPIOEFEN |= BIT(4);
  151. GPIOEDE |= BIT(4);
  152. GPIOEDIR &= ~BIT(4);
  153. } else {
  154. TRACE("MCLK_OUT_DIS ");
  155. }
  156. } else { //SLAVE: BCLK,LRC in
  157. TRACE("SLAVE ");
  158. GPIOEFEN |= (BIT(5) | BIT(6));
  159. GPIOEDE |= (BIT(5) | BIT(6));
  160. GPIOEDIR |= (BIT(5) | BIT(6));
  161. GPIOEPU |= (BIT(5) | BIT(6));
  162. }
  163. if (iis_mode & IISCFG_TX) { //DO out
  164. TRACE("TX_DO_OUT ");
  165. GPIOEFEN |= BIT(7);
  166. GPIOEDE |= BIT(7);
  167. GPIOEDIR &= ~BIT(7);
  168. }
  169. if (iis_mode & IISCFG_RX) { //DI in
  170. TRACE("RX_DI_IN ");
  171. if (iis_mode & IISCFG_ONEWIRE)//单线模式
  172. {
  173. TRACE("iis one wire io");
  174. GPIOEFEN |= BIT(7);
  175. GPIOEDE |= BIT(7);
  176. GPIOEDIR |= BIT(7);
  177. GPIOEPU |= BIT(7);
  178. } else {
  179. GPIOEFEN |= BIT(0);
  180. GPIOEDE |= BIT(0);
  181. GPIOEDIR |= BIT(0);
  182. GPIOEPU |= BIT(0);
  183. }
  184. }
  185. } else if (IIS_G3 == io_map) {
  186. TRACE("IIS_G3, MCLK_PB4, BCLK_PB0, LRC_PB1, DO_PB2, DI_PB5\n");
  187. FUNCMCON2 |= 0x03;
  188. if (iis_mode & IISCFG_MASTER) { //MASTER,BCLK,LRC,MCLK out
  189. TRACE("MASTER ");
  190. GPIOBFEN |= (BIT(0) | BIT(1));
  191. GPIOBDE |= (BIT(0) | BIT(1));
  192. GPIOBDIR &= ~(BIT(0) | BIT(1));
  193. if (mclk_out_en) {
  194. TRACE("MCLK_OUT_EN ");
  195. GPIOBFEN |= BIT(4);
  196. GPIOBDE |= BIT(4);
  197. GPIOBDIR &= ~BIT(4);
  198. } else {
  199. TRACE("MCLK_OUT_DIS ");
  200. }
  201. } else { //SLAVE: BCLK,LRC in
  202. TRACE("SLAVE ");
  203. GPIOBFEN |= (BIT(0) | BIT(1));
  204. GPIOBDE |= (BIT(0) | BIT(1));
  205. GPIOBDIR |= (BIT(0) | BIT(1));
  206. GPIOBPU |= (BIT(0) | BIT(1));
  207. }
  208. if (iis_mode & IISCFG_TX) { //DO out
  209. TRACE("TX_DO_OUT ");
  210. GPIOBFEN |= BIT(2);
  211. GPIOBDE |= BIT(2);
  212. GPIOBDIR &= ~BIT(2);
  213. }
  214. if (iis_mode & IISCFG_RX) { //DI in
  215. TRACE("RX_DI_IN ");
  216. if (iis_mode & IISCFG_ONEWIRE) //单线模式
  217. {
  218. TRACE("iis one wire io");
  219. GPIOBFEN |= BIT(2);
  220. GPIOBDE |= BIT(2);
  221. GPIOBDIR |= BIT(2);
  222. GPIOBPU |= BIT(2);
  223. } else {
  224. GPIOBFEN |= BIT(5);
  225. GPIOBDE |= BIT(5);
  226. GPIOBDIR |= BIT(5);
  227. GPIOBPU |= BIT(5);
  228. }
  229. }
  230. }
  231. TRACE("\n");
  232. return 0;
  233. }
  234. AT(.com_text.iis_code)
  235. u32 iis_tx_dma_addr_inc(void) //得到可用地址后,自增 //buf结构: TX_RX同时存在时前一半是TX,后一版半是RX, 如果只有TX或RX,则全部用于TX或RX
  236. {
  237. u32 buf_idx = iis_libcfg->dma_cfg.txbuf_idx;
  238. u8* buf_start = iis_libcfg->dma_cfg.txbuf_start_addr;
  239. u32 addr = (u32)(buf_start+buf_idx);
  240. if (buf_idx) {
  241. iis_libcfg->dma_cfg.txbuf_idx = 0;
  242. } else {
  243. iis_libcfg->dma_cfg.txbuf_idx = IISDMACNT*4;
  244. }
  245. return addr;
  246. }
  247. AT(.com_text.iis_code)
  248. u32 iis_rx_dma_addr_inc(void) //得到可用地址后,自增 //buf结构: TX_RX同时存在时前一半是TX,后一版半是RX, 如果只有TX或RX,则全部用于TX或RX
  249. {
  250. u32 buf_idx = iis_libcfg->dma_cfg.rxbuf_idx;
  251. u8* buf_start = iis_libcfg->dma_cfg.rxbuf_start_addr;
  252. u32 addr = (u32)(buf_start+buf_idx);
  253. if (buf_idx) {
  254. iis_libcfg->dma_cfg.rxbuf_idx = 0;
  255. } else {
  256. iis_libcfg->dma_cfg.rxbuf_idx = IISDMACNT*4;
  257. }
  258. return addr;
  259. }
  260. //iis_clk_ch: 2_adda_clk
  261. //iis_clk_div: iis_clk_ch 配置为3时可以选分频系数
  262. void iis_clk_set(u32 iis_clk_ch, u32 iis_clk_div)
  263. {
  264. CLKCON1 = (CLKCON1 & ~(0x03<<28)) | (iis_clk_ch << 28); //select addc_clk
  265. CLKDIVCON0 = (CLKDIVCON0 & ~(0x0F<<28)) | (iis_clk_div << 28); //iis_div 1
  266. CLKGAT0 |= BIT(10);
  267. }
  268. void iis_clk_div_set(u16 spr_value, u16 mclk_fs, u8 bitmode)
  269. {
  270. u8 mclk_div = 0, bclk_div = 0, bits_in_sample =(bitmode?64:32);
  271. u32 interface_clk = 24576000;
  272. if (spr_value % 1000) { //adpll输出44.1k
  273. adpll_spr_set(0);
  274. } else { //adpll输出48k
  275. adpll_spr_set(1);
  276. }
  277. if (spr_value == IIS_SPR_44100) {
  278. spr_value = IIS_SPR_48000; //44.1k按照48k计算
  279. }
  280. mclk_div = interface_clk / (spr_value*mclk_fs);
  281. bclk_div = mclk_fs / bits_in_sample;
  282. if (bclk_div == 1) {
  283. printf("\nERROR:FS in the current bitmode is supported\n\n");
  284. WDT_RST();
  285. }
  286. TRACE("mclk_div:%d, bclk_div:%d\n",mclk_div,bclk_div);
  287. IISBAUD = (((bclk_div-1)&0x1f)<<7 | ((mclk_div-1)&0x3f));
  288. }
  289. void iis_cfg_init(iis_cfg_t *cfg)
  290. {
  291. TRACE("%s\n", __func__);
  292. u32 iisconsfr = 0;
  293. iis_libcfg = cfg;
  294. iis_io_init(iis_libcfg->iomap,iis_libcfg->mode,iis_libcfg->mclk_out_en);
  295. iis_clk_set(2, 1); //i2s clk sel dac_clk
  296. SETB(IISCON0, 16); //clear tx pending
  297. SETB(IISCON0, 17); //clear rx pending
  298. IISCON0 = 0;
  299. if (iis_libcfg->mode & IISCFG_DMA) {
  300. iis_irq_init();
  301. if (iis_libcfg->bit_mode == IIS_32BIT) {
  302. IISDMACNT = iis_libcfg->dma_cfg.samples * 2; //32bit模式时一个samples对应64bit
  303. } else if (iis_libcfg->bit_mode == IIS_16BIT) {
  304. IISDMACNT = iis_libcfg->dma_cfg.samples;
  305. }
  306. if (((iis_libcfg->mode & IISCFG_TXMASK) == IISCFG_RAMTX) && ((iis_libcfg->mode & IISCFG_RXMASK) == IISCFG_RAMRX)) {
  307. u32 required_len = IISDMACNT*4*2*2;
  308. if (required_len > iis_libcfg->dma_cfg.dmabuf_len) {
  309. printf("\nERROR:dmabuf_len is no enough\n\n");
  310. WDT_RST();
  311. }
  312. iis_libcfg->dma_cfg.txbuf_start_addr = iis_libcfg->dma_cfg.dmabuf_ptr;
  313. iis_libcfg->dma_cfg.rxbuf_start_addr = iis_libcfg->dma_cfg.dmabuf_ptr + IISDMACNT*4*2;
  314. iis_libcfg->dma_cfg.txbuf_idx = 0;
  315. iis_libcfg->dma_cfg.rxbuf_idx = 0;
  316. IISDMAOADR0 = iis_tx_dma_addr_inc();
  317. IISDMAOADR1 = iis_tx_dma_addr_inc();
  318. IISDMAIADR0 = iis_rx_dma_addr_inc();
  319. IISDMAIADR1 = iis_rx_dma_addr_inc();
  320. } else if (((iis_libcfg->mode & IISCFG_TXMASK) == IISCFG_RAMTX) && ((iis_libcfg->mode & IISCFG_RXMASK) != IISCFG_RAMRX)) {
  321. u32 required_len = IISDMACNT*4*2;
  322. if (required_len > iis_libcfg->dma_cfg.dmabuf_len) {
  323. printf("\nERROR:dmabuf_len is no enough\n\n");
  324. WDT_RST();
  325. }
  326. iis_libcfg->dma_cfg.txbuf_start_addr = iis_libcfg->dma_cfg.dmabuf_ptr;
  327. iis_libcfg->dma_cfg.txbuf_idx = 0;
  328. IISDMAOADR0 = iis_tx_dma_addr_inc();
  329. IISDMAOADR1 = iis_tx_dma_addr_inc();
  330. } else if (((iis_libcfg->mode & IISCFG_TXMASK) != IISCFG_RAMTX) && ((iis_libcfg->mode & IISCFG_RXMASK) == IISCFG_RAMRX)){
  331. u32 required_len = IISDMACNT*4*2;
  332. if (required_len > iis_libcfg->dma_cfg.dmabuf_len) {
  333. printf("\nERROR:dmabuf_len is no enough\n\n");
  334. WDT_RST();
  335. }
  336. iis_libcfg->dma_cfg.rxbuf_start_addr = iis_libcfg->dma_cfg.dmabuf_ptr;
  337. iis_libcfg->dma_cfg.rxbuf_idx = 0;
  338. IISDMAIADR0 = iis_rx_dma_addr_inc();
  339. IISDMAIADR1 = iis_rx_dma_addr_inc();
  340. if(iis_libcfg->mode & IISCFG_ONEWIRE){ //单线
  341. TRACE("iis one wire\n");
  342. SETB(iisconsfr, 12);
  343. SETB(iisconsfr, 13);
  344. }else{
  345. TRACE("iis two wire\n");
  346. CLRB(iisconsfr, 12);
  347. CLRB(iisconsfr, 13);
  348. }
  349. }
  350. }
  351. iis_clk_div_set(iis_libcfg->spr_sel, iis_libcfg->mclk_sel, iis_libcfg->bit_mode);
  352. if (IIS_16BIT == iis_libcfg->bit_mode) {
  353. CLRB(iisconsfr, 2); //0: iis bit mode (0:16bit) at master function
  354. } else if(IIS_32BIT == iis_libcfg->bit_mode) {
  355. SETB(iisconsfr, 2); //1: iis bit mode (1:32bit) at master function
  356. }
  357. if (IIS_DATA_LEFT_JUSTIFIED == iis_libcfg->data_mode) {
  358. CLRB(iisconsfr, 3); //0: left-justified mode (data delay 0 clock after WS change)
  359. } else if (IIS_DATA_NORMAL == iis_libcfg->data_mode) {
  360. SETB(iisconsfr, 3); //1: IIS normal mode (data delay 1 clock after WS change)
  361. }
  362. SETB(iisconsfr, 10); //dma out requet mask delay eanble (system very fast,need set this)
  363. if (iis_libcfg->mode & IISCFG_MASTER) {
  364. CLRB(iisconsfr, 1); //0 iis is master mode
  365. } else {
  366. SETB(iisconsfr, 1); //1 iis is slave mode
  367. }
  368. if (iis_libcfg->mclk_out_en) {
  369. SETB(iisconsfr, 9);
  370. }
  371. if (iis_libcfg->mode & IISCFG_DMA) {
  372. if ((iis_libcfg->mode & IISCFG_TXMASK) == IISCFG_RAMTX) {
  373. TRACE("iis ram tx int en\n");
  374. SETB(iisconsfr, 5); //iis DMA output enable
  375. SETB(iisconsfr, 7); //dma output interrupt enable
  376. SETB(iisconsfr, 4); //data OUT source select: RAM
  377. }
  378. if ((iis_libcfg->mode & IISCFG_RXMASK) == IISCFG_RAMRX) {
  379. TRACE("iis ram rx int en\n");
  380. SETB(iisconsfr, 6); //iis DMA input enable
  381. SETB(iisconsfr, 8); //dma input interrupt enable
  382. }
  383. if ((iis_libcfg->mode & IISCFG_TXRXMASK) == IISCFG_RAMRX) { //只有RAMRX 需要把这位置起来才会KICK起来,同时有打开SRCTX时则可以不用设置它
  384. TRACE("iis only ram rx,bit4 set\n");
  385. SETB(iisconsfr, 4);
  386. }
  387. }
  388. CLRB(iisconsfr, 0); //IIS EN,先屏蔽,由iis_start在需要时才打开
  389. if (iis_libcfg->mode & IISCFG_SRC) {
  390. TRACE("iis src out en\n");
  391. DACDIGCON0 |= BIT(23);
  392. } else {
  393. DACDIGCON0 &= ~BIT(23);
  394. }
  395. IISCON0 = iisconsfr; //config iis sfor
  396. #if TRACE_EN
  397. iis_mode_info_print();
  398. iis_sfr_info_dump();
  399. #endif
  400. }
  401. void iis_start(void)
  402. {
  403. TRACE("-->%s\n",__func__);
  404. dac_fade_in();
  405. SETB(IISCON0, 0);
  406. }
  407. void iis_stop(void)
  408. {
  409. TRACE("-->%s\n",__func__);
  410. dac_fade_out();
  411. CLRB(IISCON0, 0);
  412. }
  413. AT(.com_text.iis_code)
  414. u8 iis_mode_cfg_get(void)
  415. {
  416. if (iis_libcfg) {
  417. return iis_libcfg->mode;
  418. } else {
  419. return 0;
  420. }
  421. }
  422. AT(.com_text.iis_code)
  423. void iis_isr_func(void)
  424. {
  425. u32 cache_addr;
  426. u32 iiscon0 = IISCON0 & (~(BIT(16)|BIT(17)));
  427. if (IISCON0 & BIT(16)) { //TX ISR
  428. IISCON0 = iiscon0 | BIT(16);
  429. cache_addr = iis_tx_dma_addr_inc();
  430. IISDMAOADR1 = cache_addr;
  431. if (iis_libcfg->dma_cfg.iis_isr_tx_callbck) {
  432. iis_libcfg->dma_cfg.iis_isr_tx_callbck((void*)cache_addr,iis_libcfg->dma_cfg.samples,IISCON0 & BIT(2));
  433. }
  434. }
  435. if (IISCON0 & BIT(17)) { //RX ISR
  436. IISCON0 = iiscon0 | BIT(17);
  437. cache_addr = iis_rx_dma_addr_inc();
  438. IISDMAIADR1 = cache_addr;
  439. if (iis_libcfg->dma_cfg.iis_isr_rx_callbck) {
  440. iis_libcfg->dma_cfg.iis_isr_rx_callbck((void*)cache_addr,iis_libcfg->dma_cfg.samples,IISCON0 & BIT(2));
  441. }
  442. }
  443. }
  444. void iis_irq_init(void)
  445. {
  446. TRACE("%s\n", __func__);
  447. register_isr(IRQ_I2S_VECTOR, iis_isr_func);
  448. PICPR &= ~BIT(IRQ_I2S_VECTOR);
  449. PICEN |= BIT(IRQ_I2S_VECTOR);
  450. }
  451. #if IIS_TEST_DEMO
  452. #define IIS_DMA_SAMPLES 32
  453. #define IIS_DMABUF_LEN (IIS_DMA_SAMPLES * 8 * 2 * 2) //(samples:240)*(sample_len:8)*(dmabuf_switching:2)*(txrx:2)
  454. iis_cfg_t iis_cfg;
  455. u8 iis_dmabuf[IIS_DMABUF_LEN] AT(.iis_dmabuf); //若iis_cfg.mode中有RAMTX或RAMRX,需要该dmabuf做中断缓存
  456. AT(.com_text.iis_code)
  457. void aubuf_adjust(void)
  458. {
  459. u16 au_size = (u16)AUBUF0SIZE >> 2; //1/4 AUBUFSIZE
  460. u16 aubuf_fifo_cnt = AUBUF0FIFOCNT & 0xffff;
  461. if(CKB0(DACDIGCON0,6)) { //phasecomp sync enable
  462. SETB(DACDIGCON0,6);
  463. }
  464. if (aubuf_fifo_cnt <= au_size) {
  465. PHASECOMP = 0xFFFE; //低16位有符号数调节SRC0 FIFO SPEED
  466. } else if (aubuf_fifo_cnt >= (au_size*3)) {
  467. PHASECOMP = 0x0001;
  468. } else {
  469. PHASECOMP = 0;
  470. }
  471. }
  472. AT(.com_text.iis_code)
  473. void iis_tx_process_test(void *buf, u32 samples, bool iis_32bit)
  474. {
  475. static u8 cnt = 0;
  476. u32 *ptr32 = (u32*)buf;
  477. u16 *ptr16 = (u16*)buf;
  478. for (int i = 0; i< samples;i++) {
  479. if (iis_32bit) {
  480. ptr32[2*i] = cnt; //16->32位扩展
  481. ptr32[2*i+1] = cnt;
  482. } else {
  483. ptr16[2*i] = cnt; //16->32位扩展
  484. ptr16[2*i+1] = cnt;
  485. }
  486. }
  487. cnt++;
  488. #if TRACE_EN
  489. static u32 ticks = 0;
  490. static u32 isr_cnt = 0;
  491. isr_cnt++;
  492. if (tick_check_expire(ticks,1000)) {
  493. printk(str_iistx_info,IS_IIS_MASTER(),samples, isr_cnt, samples*isr_cnt);
  494. isr_cnt = 0;
  495. ticks = tick_get();
  496. }
  497. #endif
  498. }
  499. AT(.com_text.iis_code)
  500. void iis_rx_process_test(void *buf, u32 samples, bool iis_32bit)
  501. {
  502. u32 *ptr32 = (u32*)buf;
  503. u16 *ptr16 = (u16*)buf;
  504. if (!(iis_mode_cfg_get() & IISCFG_MASTER)) { //slave rx需要进行调速
  505. aubuf_adjust();
  506. }
  507. for (int i = 0; i < samples; i++) {
  508. if (iis_32bit) {
  509. dac_put_sample_24bit(ptr32[2*i]>>8, ptr32[2*i+1]>>8);
  510. } else {
  511. dac_put_sample_16bit(ptr16[2*i], ptr16[2*i+1]);
  512. }
  513. }
  514. }
  515. void bsp_iis_test_init(void)
  516. {
  517. printf("%s\n",__func__);
  518. memset(&iis_cfg, 0x00, sizeof(iis_cfg));
  519. iis_cfg.mode = IIS_MASTER_RAMTX_RAMRX;
  520. iis_cfg.iomap = IIS_G3;
  521. iis_cfg.bit_mode = IIS_32BIT;
  522. iis_cfg.data_mode = IIS_DATA_NORMAL;
  523. iis_cfg.spr_sel = IIS_SPR_48000;
  524. iis_cfg.mclk_sel = IIS_MCLK_128FS;
  525. iis_cfg.mclk_out_en = IIS_MCLK_OUT_DIS;
  526. if (iis_cfg.mode & IISCFG_DMA) {
  527. printf("iis_dma config run\n");
  528. iis_cfg.dma_cfg.samples = IIS_DMA_SAMPLES;
  529. iis_cfg.dma_cfg.dmabuf_ptr = iis_dmabuf;
  530. iis_cfg.dma_cfg.dmabuf_len = IIS_DMABUF_LEN;
  531. iis_cfg.dma_cfg.iis_isr_rx_callbck = iis_rx_process_test; //iis_rx接收完一个DMA后起中断,回调该函数,可以从buf中取出接收到数据
  532. iis_cfg.dma_cfg.iis_isr_tx_callbck = iis_tx_process_test; //iis_tx发送完一个DMA后起中断,要求向buf中填入数据,以备下一次发送
  533. }
  534. dac_aubuf_init();
  535. dac_spr_set(SPR_48000); //设置采样率
  536. dac_fade_in(); //dac淡入
  537. dac_vol_set(0x3000); //首次进入i2s,dac的默认音量, 可填0~0x7fff
  538. dac_put_zero(256); //初始化256个样点
  539. iis_cfg_init(&iis_cfg); //初始化iis配置
  540. iis_start();
  541. }
  542. #endif
  543. #if IIS_RX2SCO_EN
  544. #define IIS_SCO_DMA_SAMPLES 240
  545. #define IIS_SCO_DMABUF_LEN (IIS_SCO_DMA_SAMPLES * 4 * 2) //(samples:240)*(sample_len:4)*(dmabuf_switching:2)
  546. iis_cfg_t iis_sco_cfg AT(.bss.iis.sco);
  547. u8 iis_sco_dmabuf[IIS_SCO_DMABUF_LEN] AT(.buf.iis.sco);
  548. struct iis_cvsd_cb_t{
  549. u8 tmpbuf[240*2];
  550. u8 wcnt;
  551. } iis_cvsd_cb AT(.buf.iis.sco);
  552. AT(.com_text.iis_code)
  553. void iis_rx_2_sco_process(void *buf, u32 samples, bool iis_32bit)
  554. {
  555. u8 *output_buf = NULL;
  556. u16 *ptr16 = (u16*)buf;
  557. if ((samples != 240)||(iis_32bit ==1)) { //for only 16bit mode
  558. return;
  559. }
  560. if (!bt_sco_is_msbc() && !bt_sco_dnn_en()) {
  561. for (int i = 0; i < 120; i++) {
  562. ptr16[i] = ptr16[4*i];
  563. }
  564. memcpy(iis_cvsd_cb.tmpbuf + (iis_cvsd_cb.wcnt++)*120*2, buf, 120*2);
  565. if (iis_cvsd_cb.wcnt >= 2) {
  566. iis_cvsd_cb.wcnt = 0;
  567. output_buf = (u8*)iis_cvsd_cb.tmpbuf;
  568. }
  569. } else {
  570. for (int i = 0; i < 240; i++) {
  571. ptr16[i] = ptr16[2*i];
  572. }
  573. output_buf = (u8*)buf;
  574. }
  575. if (output_buf) {
  576. #if BT_AEC_EN || BT_SCO_SMIC_EN || BT_SCO_DMIC_EN
  577. bt_aec_process(output_buf, 240, 0);
  578. #else
  579. bt_sco_tx_process(output_buf, 240, 0);
  580. #endif
  581. }
  582. }
  583. void bsp_iis_sco_init(void)
  584. {
  585. printf("%s\n",__func__);
  586. memset(&iis_sco_cfg, 0x00, sizeof(iis_sco_cfg));
  587. iis_sco_cfg.mode = IIS_MASTER_RAMRX_ONEWIRE;
  588. iis_sco_cfg.iomap = IIS_G3;
  589. iis_sco_cfg.bit_mode = IIS_16BIT;
  590. iis_sco_cfg.data_mode = IIS_DATA_NORMAL;
  591. iis_sco_cfg.spr_sel = IIS_SPR_16000;
  592. iis_sco_cfg.mclk_sel = IIS_MCLK_128FS;
  593. iis_sco_cfg.mclk_out_en = IIS_MCLK_OUT_DIS;
  594. if (iis_sco_cfg.mode & IISCFG_DMA) {
  595. iis_sco_cfg.dma_cfg.samples = IIS_SCO_DMA_SAMPLES;
  596. iis_sco_cfg.dma_cfg.dmabuf_ptr = iis_sco_dmabuf;
  597. iis_sco_cfg.dma_cfg.dmabuf_len = sizeof(iis_sco_dmabuf);
  598. iis_sco_cfg.dma_cfg.iis_isr_rx_callbck = iis_rx_2_sco_process;
  599. iis_sco_cfg.dma_cfg.iis_isr_tx_callbck = NULL;
  600. }
  601. iis_cfg_init(&iis_sco_cfg);
  602. memset(&iis_cvsd_cb, 0x00, sizeof(iis_cvsd_cb));
  603. }
  604. #endif
  605. #endif // I2S_EN