123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653 |
- #include "include.h"
- #if IIS_EN
- #define IIS_TEST_DEMO 1
- #define TRACE_EN 0
- #if TRACE_EN
- #define TRACE(...) printf(__VA_ARGS__)
- #else
- #define TRACE(...)
- #endif
- iis_cfg_t *iis_libcfg;
- ///计算IIS模块时钟分频比的方法
- //计算方法:mclk = 参考时钟/(mdiv+1) //这里的参考时钟即PLL1DIV
- // bclk = mclk/(bdiv+1)(不能1分频)
- // lrclk = 采样率 = bclk/(位数*2)
- //fs实际上是指 MCLK/LRC // MCLK = fs * LRC
- //IISBAUD[6:0] mclk_div
- //IISBAUD[11:7] bclk_div
- //IIS时钟源默认和DAC是一样的,更改IIS采样率(IIS_LRC)需要参考当前DAC的采样率DAC_OUT_SPR (设置为44.1K或48K)
- //16 BIT时钟分频配置
- //LRC为44.1K时:
- //16bit: BCLK = 44.1K*32 = 1.4112M
- //64fs: 44.1K * 32 *2 (bdiv) = 2.8224M = MCLK //(MCLK * mdiv_8) = 22.5792M
- //128fs: 44.1K * 32 *4(bdiv) = 5.644.8M = MCLK //(MCLK * mdiv_4) = 22.5792M
- //256fs: 44.1K * 32 *8 (bdiv) = 11. 2896M = MCLK //(MCLK * mdiv_2) = 22.5792M
- //LRC为48K时:
- //16bit: BCLK = 48K*32 = 1.536M
- //64fs: 48K * 32 *2 (bdiv) = 3.072M = MCLK //(MCLK * mdiv_8) = 24.576M
- //128fs: 48K * 32 *4 (bdiv) = 6.144M = MCLK //(MCLK * mdiv_4) = 24.576M
- //256fs: 48K * 32 *8 (bdiv) = 12.288M = MCLK //(MCLK * mdiv_2) = 24.576M
- u8 i2s_16bit_clk_div[3][2] = {
- //bclkdiv ////mclk_div
- {2-1, 8-1}, //64fs
- {4-1, 4-1}, //128fs
- {8-1, 6-1}, //16k, no 256fs for 48k,
- };
- //32 BIT时钟分频配置
- //LRC为44.1K时:
- //32bit: BCLK = 44.1K*32 = 2.8224M
- //64fs: 44.1K * 64 *8 (bdiv) = 22.5792M = MCLK //(MCLK * mdiv_1) = 22.5792M
- //128fs: 44.1K * 64 *2 (bdiv) = 5.644.8M = MCLK //(MCLK * mdiv_4) = 22.5792M
- //256fs: 44.1K * 64 *4 (bdiv) = 11.289.6M = MCLK //(MCLK * mdiv_2) = 22.5792M
- //LRC为48K时:
- //32bit: BCLK = 48K * 64 = 3.072M
- //64fs: 48K * 64 *8 (bdiv) = 24.576M = MCLK //(MCLK * mdiv_1) = 24.576M
- //128fs: 48K * 64 *2 (bdiv) = 6.144M = MCLK //(MCLK * mdiv_1) = 24.576M
- //256fs: 48K * 64 *4 (bdiv) = 12.288M = MCLK //(MCLK * mdiv_1) = 24.576M
- u8 i2s_32bit_clk_div[3][2] = {
- //bclkdiv //mclk_div
- {8-1,1-1}, //64fs
- {2-1,4-1}, //128fs
- {4-1,2-1}, //256fs
- };
- ///--------------------------------------------------------
- #if TRACE_EN
- AT(.com_text.iis_cst)
- const char str_iistx_info[] = "IISTX: master = %d, samples = %d, isrcnt = %d (SR_%d)\n";
- const IIS_MODE_INFO_TBL iis_mode_info_tbl[10] = {
- {IIS_MASTER_SRCTX, "IIS_MASTER_SRCTX",},
- {IIS_MASTER_RAMTX, "IIS_MASTER_RAMTX",},
- {IIS_MASTER_RAMTX_RAMRX, "IIS_MASTER_RAMTX_RAMRX",},
- {IIS_MASTER_SRCTX_RAMRX, "IIS_MASTER_SRCTX_RAMRX",},
- {IIS_MASTER_RAMRX, "IIS_MASTER_RAMRX",},
- {IIS_MASTER_RAMRX_ONEWIRE, "IIS_MASTER_RAMRX_ONEWIRE"},
- {IIS_SLAVE_RAMRX, "IIS_SLAVE_RAMRX",},
- {IIS_SLAVE_RAMRX_ONEWIRE, "IIS_SLAVE_RAMRX_ONEWIRE",},
- {IIS_SLAVE_RAMTX, "IIS_SLAVE_RAMTX",},
- {IIS_SLAVE_RAMTX_RAMRX, "IIS_SLAVE_RAMTX_RAMRX",},
- };
- void iis_mode_info_print(void)
- {
- for (int i = 0; i < 10; i++) {
- if (iis_mode_info_tbl[i].iis_mode == iis_libcfg->mode) {
- TRACE("iis_mode[0x%X] = %s\n", iis_libcfg->mode, iis_mode_info_tbl[i].iis_str_info);
- break;
- }
- }
- }
- void iis_sfr_info_dump(void)
- {
- TRACE("\ndump iis sfr info:\n");
- TRACE("IISCON0 = 0x%X\n",IISCON0);
- TRACE("IISBAUD = 0x%X, IISDMACNT = 0x%X_%d\n", IISBAUD, IISDMACNT, IISDMACNT);
- TRACE("IISDMAOADR0 = 0x%X, IISDMAOADR1 = 0x%X\n", IISDMAOADR0, IISDMAOADR1);
- TRACE("IISDMAIADR0 = 0x%X, IISDMAIADR1 = 0x%X\n", IISDMAIADR0, IISDMAIADR1);
- TRACE("DACDIGCON = 0x%X\n", DACDIGCON0);
- if(iis_libcfg) {
- TRACE("iis_dma_buf : 0x%X\n", iis_libcfg->dma_cfg.dmabuf_ptr);
- }
- }
- #endif
- u8 iis_io_init(TYPE_IIS_IO io_map, TYPE_IIS_MODE iis_mode, TYPE_MCLK_OUT_SEL mclk_out_en)
- {
- TRACE("%s: ",__func__);
- FUNCMCON2 = 0x0F;
- if (IIS_G1 == io_map) {
- TRACE("IIS_G1, MCLK_PA4, BCLK_PA5, LRC_PA6, DO_PA7, DI_PB3\n");
- FUNCMCON2 |= 0x01;
- if (iis_mode & IISCFG_MASTER) { //MASTER,BCLK,LRC,MCLK out
- TRACE("MASTER ");
- GPIOAFEN |= (BIT(5) | BIT(6));
- GPIOADE |= (BIT(5) | BIT(6));
- GPIOADIR &= ~(BIT(5) | BIT(6));
- if (mclk_out_en) {
- TRACE("MCLK_OUT_EN ");
- GPIOAFEN |= BIT(4);
- GPIOADE |= BIT(4);
- GPIOADIR &= ~ BIT(4);
- } else {
- TRACE("MCLK_OUT_DIS ");
- }
- } else { //SLAVE: BCLK,LRC in
- TRACE("SLAVE ");
- GPIOAFEN |= (BIT(5) | BIT(6));
- GPIOADE |= (BIT(5) | BIT(6));
- GPIOADIR |= (BIT(5) | BIT(6));
- GPIOAPU |= (BIT(5) | BIT(6));
- }
- if (iis_mode & IISCFG_TX) { //DO out
- TRACE("TX_DO_OUT ");
- GPIOAFEN |= BIT(7);
- GPIOADE |= BIT(7);
- GPIOADIR &= ~BIT(7);
- }
- if (iis_mode & IISCFG_RX) { //DI in
- TRACE("RX_DI_IN ");
- if (iis_mode & IISCFG_ONEWIRE)//单线模式
- {
- TRACE("iis one wire io");
- GPIOAFEN |= BIT(7);
- GPIOADE |= BIT(7);
- GPIOADIR |= BIT(7);
- GPIOAPU |= BIT(7);
- } else {
- GPIOBFEN |= BIT(3);
- GPIOBDE |= BIT(3);
- GPIOBDIR |= BIT(3);
- GPIOBPU |= BIT(3);
- }
- }
- } else if (IIS_G2 == io_map) {
- TRACE("IIS_G2, MCLK_PE4, BCLK_PE5, LRC_PE6, DO_PE7, DI_PE0\n");
- FUNCMCON2 |= 0x02;
- if (iis_mode & IISCFG_MASTER) { //MASTER,BCLK,LRC,MCLK out
- TRACE("MASTER ");
- GPIOEFEN |= (BIT(5) | BIT(6));
- GPIOEDE |= (BIT(5) | BIT(6));
- GPIOEDIR &= ~(BIT(5) | BIT(6));
- if (mclk_out_en) {
- TRACE("MCLK_OUT_EN ");
- GPIOEFEN |= BIT(4);
- GPIOEDE |= BIT(4);
- GPIOEDIR &= ~BIT(4);
- } else {
- TRACE("MCLK_OUT_DIS ");
- }
- } else { //SLAVE: BCLK,LRC in
- TRACE("SLAVE ");
- GPIOEFEN |= (BIT(5) | BIT(6));
- GPIOEDE |= (BIT(5) | BIT(6));
- GPIOEDIR |= (BIT(5) | BIT(6));
- GPIOEPU |= (BIT(5) | BIT(6));
- }
- if (iis_mode & IISCFG_TX) { //DO out
- TRACE("TX_DO_OUT ");
- GPIOEFEN |= BIT(7);
- GPIOEDE |= BIT(7);
- GPIOEDIR &= ~BIT(7);
- }
- if (iis_mode & IISCFG_RX) { //DI in
- TRACE("RX_DI_IN ");
- if (iis_mode & IISCFG_ONEWIRE)//单线模式
- {
- TRACE("iis one wire io");
- GPIOEFEN |= BIT(7);
- GPIOEDE |= BIT(7);
- GPIOEDIR |= BIT(7);
- GPIOEPU |= BIT(7);
- } else {
- GPIOEFEN |= BIT(0);
- GPIOEDE |= BIT(0);
- GPIOEDIR |= BIT(0);
- GPIOEPU |= BIT(0);
- }
- }
- } else if (IIS_G3 == io_map) {
- TRACE("IIS_G3, MCLK_PB4, BCLK_PB0, LRC_PB1, DO_PB2, DI_PB5\n");
- FUNCMCON2 |= 0x03;
- if (iis_mode & IISCFG_MASTER) { //MASTER,BCLK,LRC,MCLK out
- TRACE("MASTER ");
- GPIOBFEN |= (BIT(0) | BIT(1));
- GPIOBDE |= (BIT(0) | BIT(1));
- GPIOBDIR &= ~(BIT(0) | BIT(1));
- if (mclk_out_en) {
- TRACE("MCLK_OUT_EN ");
- GPIOBFEN |= BIT(4);
- GPIOBDE |= BIT(4);
- GPIOBDIR &= ~BIT(4);
- } else {
- TRACE("MCLK_OUT_DIS ");
- }
- } else { //SLAVE: BCLK,LRC in
- TRACE("SLAVE ");
- GPIOBFEN |= (BIT(0) | BIT(1));
- GPIOBDE |= (BIT(0) | BIT(1));
- GPIOBDIR |= (BIT(0) | BIT(1));
- GPIOBPU |= (BIT(0) | BIT(1));
- }
- if (iis_mode & IISCFG_TX) { //DO out
- TRACE("TX_DO_OUT ");
- GPIOBFEN |= BIT(2);
- GPIOBDE |= BIT(2);
- GPIOBDIR &= ~BIT(2);
- }
- if (iis_mode & IISCFG_RX) { //DI in
- TRACE("RX_DI_IN ");
- if (iis_mode & IISCFG_ONEWIRE) //单线模式
- {
- TRACE("iis one wire io");
- GPIOBFEN |= BIT(2);
- GPIOBDE |= BIT(2);
- GPIOBDIR |= BIT(2);
- GPIOBPU |= BIT(2);
- } else {
- GPIOBFEN |= BIT(5);
- GPIOBDE |= BIT(5);
- GPIOBDIR |= BIT(5);
- GPIOBPU |= BIT(5);
- }
- }
- }
- TRACE("\n");
- return 0;
- }
- AT(.com_text.iis_code)
- u32 iis_tx_dma_addr_inc(void) //得到可用地址后,自增 //buf结构: TX_RX同时存在时前一半是TX,后一版半是RX, 如果只有TX或RX,则全部用于TX或RX
- {
- u32 buf_idx = iis_libcfg->dma_cfg.txbuf_idx;
- u8* buf_start = iis_libcfg->dma_cfg.txbuf_start_addr;
- u32 addr = (u32)(buf_start+buf_idx);
- if (buf_idx) {
- iis_libcfg->dma_cfg.txbuf_idx = 0;
- } else {
- iis_libcfg->dma_cfg.txbuf_idx = IISDMACNT*4;
- }
- return addr;
- }
- AT(.com_text.iis_code)
- u32 iis_rx_dma_addr_inc(void) //得到可用地址后,自增 //buf结构: TX_RX同时存在时前一半是TX,后一版半是RX, 如果只有TX或RX,则全部用于TX或RX
- {
- u32 buf_idx = iis_libcfg->dma_cfg.rxbuf_idx;
- u8* buf_start = iis_libcfg->dma_cfg.rxbuf_start_addr;
- u32 addr = (u32)(buf_start+buf_idx);
- if (buf_idx) {
- iis_libcfg->dma_cfg.rxbuf_idx = 0;
- } else {
- iis_libcfg->dma_cfg.rxbuf_idx = IISDMACNT*4;
- }
- return addr;
- }
- //iis_clk_ch: 2_adda_clk
- //iis_clk_div: iis_clk_ch 配置为3时可以选分频系数
- void iis_clk_set(u32 iis_clk_ch, u32 iis_clk_div)
- {
- CLKCON1 = (CLKCON1 & ~(0x03<<28)) | (iis_clk_ch << 28); //select addc_clk
- CLKDIVCON0 = (CLKDIVCON0 & ~(0x0F<<28)) | (iis_clk_div << 28); //iis_div 1
- CLKGAT0 |= BIT(10);
- }
- void iis_clk_div_set(u16 spr_value, u16 mclk_fs, u8 bitmode)
- {
- u8 mclk_div = 0, bclk_div = 0, bits_in_sample =(bitmode?64:32);
- u32 interface_clk = 24576000;
- if (spr_value % 1000) { //adpll输出44.1k
- adpll_spr_set(0);
- } else { //adpll输出48k
- adpll_spr_set(1);
- }
- if (spr_value == IIS_SPR_44100) {
- spr_value = IIS_SPR_48000; //44.1k按照48k计算
- }
- mclk_div = interface_clk / (spr_value*mclk_fs);
- bclk_div = mclk_fs / bits_in_sample;
- if (bclk_div == 1) {
- printf("\nERROR:FS in the current bitmode is supported\n\n");
- WDT_RST();
- }
- TRACE("mclk_div:%d, bclk_div:%d\n",mclk_div,bclk_div);
- IISBAUD = (((bclk_div-1)&0x1f)<<7 | ((mclk_div-1)&0x3f));
- }
- void iis_cfg_init(iis_cfg_t *cfg)
- {
- TRACE("%s\n", __func__);
- u32 iisconsfr = 0;
- iis_libcfg = cfg;
- iis_io_init(iis_libcfg->iomap,iis_libcfg->mode,iis_libcfg->mclk_out_en);
- iis_clk_set(2, 1); //i2s clk sel dac_clk
- SETB(IISCON0, 16); //clear tx pending
- SETB(IISCON0, 17); //clear rx pending
- IISCON0 = 0;
- if (iis_libcfg->mode & IISCFG_DMA) {
- iis_irq_init();
- if (iis_libcfg->bit_mode == IIS_32BIT) {
- IISDMACNT = iis_libcfg->dma_cfg.samples * 2; //32bit模式时一个samples对应64bit
- } else if (iis_libcfg->bit_mode == IIS_16BIT) {
- IISDMACNT = iis_libcfg->dma_cfg.samples;
- }
- if (((iis_libcfg->mode & IISCFG_TXMASK) == IISCFG_RAMTX) && ((iis_libcfg->mode & IISCFG_RXMASK) == IISCFG_RAMRX)) {
- u32 required_len = IISDMACNT*4*2*2;
- if (required_len > iis_libcfg->dma_cfg.dmabuf_len) {
- printf("\nERROR:dmabuf_len is no enough\n\n");
- WDT_RST();
- }
- iis_libcfg->dma_cfg.txbuf_start_addr = iis_libcfg->dma_cfg.dmabuf_ptr;
- iis_libcfg->dma_cfg.rxbuf_start_addr = iis_libcfg->dma_cfg.dmabuf_ptr + IISDMACNT*4*2;
- iis_libcfg->dma_cfg.txbuf_idx = 0;
- iis_libcfg->dma_cfg.rxbuf_idx = 0;
- IISDMAOADR0 = iis_tx_dma_addr_inc();
- IISDMAOADR1 = iis_tx_dma_addr_inc();
- IISDMAIADR0 = iis_rx_dma_addr_inc();
- IISDMAIADR1 = iis_rx_dma_addr_inc();
- } else if (((iis_libcfg->mode & IISCFG_TXMASK) == IISCFG_RAMTX) && ((iis_libcfg->mode & IISCFG_RXMASK) != IISCFG_RAMRX)) {
- u32 required_len = IISDMACNT*4*2;
- if (required_len > iis_libcfg->dma_cfg.dmabuf_len) {
- printf("\nERROR:dmabuf_len is no enough\n\n");
- WDT_RST();
- }
- iis_libcfg->dma_cfg.txbuf_start_addr = iis_libcfg->dma_cfg.dmabuf_ptr;
- iis_libcfg->dma_cfg.txbuf_idx = 0;
- IISDMAOADR0 = iis_tx_dma_addr_inc();
- IISDMAOADR1 = iis_tx_dma_addr_inc();
- } else if (((iis_libcfg->mode & IISCFG_TXMASK) != IISCFG_RAMTX) && ((iis_libcfg->mode & IISCFG_RXMASK) == IISCFG_RAMRX)){
- u32 required_len = IISDMACNT*4*2;
- if (required_len > iis_libcfg->dma_cfg.dmabuf_len) {
- printf("\nERROR:dmabuf_len is no enough\n\n");
- WDT_RST();
- }
- iis_libcfg->dma_cfg.rxbuf_start_addr = iis_libcfg->dma_cfg.dmabuf_ptr;
- iis_libcfg->dma_cfg.rxbuf_idx = 0;
- IISDMAIADR0 = iis_rx_dma_addr_inc();
- IISDMAIADR1 = iis_rx_dma_addr_inc();
- if(iis_libcfg->mode & IISCFG_ONEWIRE){ //单线
- TRACE("iis one wire\n");
- SETB(iisconsfr, 12);
- SETB(iisconsfr, 13);
- }else{
- TRACE("iis two wire\n");
- CLRB(iisconsfr, 12);
- CLRB(iisconsfr, 13);
- }
- }
- }
- iis_clk_div_set(iis_libcfg->spr_sel, iis_libcfg->mclk_sel, iis_libcfg->bit_mode);
- if (IIS_16BIT == iis_libcfg->bit_mode) {
- CLRB(iisconsfr, 2); //0: iis bit mode (0:16bit) at master function
- } else if(IIS_32BIT == iis_libcfg->bit_mode) {
- SETB(iisconsfr, 2); //1: iis bit mode (1:32bit) at master function
- }
- if (IIS_DATA_LEFT_JUSTIFIED == iis_libcfg->data_mode) {
- CLRB(iisconsfr, 3); //0: left-justified mode (data delay 0 clock after WS change)
- } else if (IIS_DATA_NORMAL == iis_libcfg->data_mode) {
- SETB(iisconsfr, 3); //1: IIS normal mode (data delay 1 clock after WS change)
- }
- SETB(iisconsfr, 10); //dma out requet mask delay eanble (system very fast,need set this)
- if (iis_libcfg->mode & IISCFG_MASTER) {
- CLRB(iisconsfr, 1); //0 iis is master mode
- } else {
- SETB(iisconsfr, 1); //1 iis is slave mode
- }
- if (iis_libcfg->mclk_out_en) {
- SETB(iisconsfr, 9);
- }
- if (iis_libcfg->mode & IISCFG_DMA) {
- if ((iis_libcfg->mode & IISCFG_TXMASK) == IISCFG_RAMTX) {
- TRACE("iis ram tx int en\n");
- SETB(iisconsfr, 5); //iis DMA output enable
- SETB(iisconsfr, 7); //dma output interrupt enable
- SETB(iisconsfr, 4); //data OUT source select: RAM
- }
- if ((iis_libcfg->mode & IISCFG_RXMASK) == IISCFG_RAMRX) {
- TRACE("iis ram rx int en\n");
- SETB(iisconsfr, 6); //iis DMA input enable
- SETB(iisconsfr, 8); //dma input interrupt enable
- }
- if ((iis_libcfg->mode & IISCFG_TXRXMASK) == IISCFG_RAMRX) { //只有RAMRX 需要把这位置起来才会KICK起来,同时有打开SRCTX时则可以不用设置它
- TRACE("iis only ram rx,bit4 set\n");
- SETB(iisconsfr, 4);
- }
- }
- CLRB(iisconsfr, 0); //IIS EN,先屏蔽,由iis_start在需要时才打开
- if (iis_libcfg->mode & IISCFG_SRC) {
- TRACE("iis src out en\n");
- DACDIGCON0 |= BIT(23);
- } else {
- DACDIGCON0 &= ~BIT(23);
- }
- IISCON0 = iisconsfr; //config iis sfor
- #if TRACE_EN
- iis_mode_info_print();
- iis_sfr_info_dump();
- #endif
- }
- void iis_start(void)
- {
- TRACE("-->%s\n",__func__);
- dac_fade_in();
- SETB(IISCON0, 0);
- }
- void iis_stop(void)
- {
- TRACE("-->%s\n",__func__);
- dac_fade_out();
- CLRB(IISCON0, 0);
- }
- AT(.com_text.iis_code)
- u8 iis_mode_cfg_get(void)
- {
- if (iis_libcfg) {
- return iis_libcfg->mode;
- } else {
- return 0;
- }
- }
- AT(.com_text.iis_code)
- void iis_isr_func(void)
- {
- u32 cache_addr;
- u32 iiscon0 = IISCON0 & (~(BIT(16)|BIT(17)));
- if (IISCON0 & BIT(16)) { //TX ISR
- IISCON0 = iiscon0 | BIT(16);
- cache_addr = iis_tx_dma_addr_inc();
- IISDMAOADR1 = cache_addr;
- if (iis_libcfg->dma_cfg.iis_isr_tx_callbck) {
- iis_libcfg->dma_cfg.iis_isr_tx_callbck((void*)cache_addr,iis_libcfg->dma_cfg.samples,IISCON0 & BIT(2));
- }
- }
- if (IISCON0 & BIT(17)) { //RX ISR
- IISCON0 = iiscon0 | BIT(17);
- cache_addr = iis_rx_dma_addr_inc();
- IISDMAIADR1 = cache_addr;
- if (iis_libcfg->dma_cfg.iis_isr_rx_callbck) {
- iis_libcfg->dma_cfg.iis_isr_rx_callbck((void*)cache_addr,iis_libcfg->dma_cfg.samples,IISCON0 & BIT(2));
- }
- }
- }
- void iis_irq_init(void)
- {
- TRACE("%s\n", __func__);
- register_isr(IRQ_I2S_VECTOR, iis_isr_func);
- PICPR &= ~BIT(IRQ_I2S_VECTOR);
- PICEN |= BIT(IRQ_I2S_VECTOR);
- }
- #if IIS_TEST_DEMO
- #define IIS_DMA_SAMPLES 32
- #define IIS_DMABUF_LEN (IIS_DMA_SAMPLES * 8 * 2 * 2) //(samples:240)*(sample_len:8)*(dmabuf_switching:2)*(txrx:2)
- iis_cfg_t iis_cfg;
- u8 iis_dmabuf[IIS_DMABUF_LEN] AT(.iis_dmabuf); //若iis_cfg.mode中有RAMTX或RAMRX,需要该dmabuf做中断缓存
- AT(.com_text.iis_code)
- void aubuf_adjust(void)
- {
- u16 au_size = (u16)AUBUF0SIZE >> 2; //1/4 AUBUFSIZE
- u16 aubuf_fifo_cnt = AUBUF0FIFOCNT & 0xffff;
- if(CKB0(DACDIGCON0,6)) { //phasecomp sync enable
- SETB(DACDIGCON0,6);
- }
- if (aubuf_fifo_cnt <= au_size) {
- PHASECOMP = 0xFFFE; //低16位有符号数调节SRC0 FIFO SPEED
- } else if (aubuf_fifo_cnt >= (au_size*3)) {
- PHASECOMP = 0x0001;
- } else {
- PHASECOMP = 0;
- }
- }
- AT(.com_text.iis_code)
- void iis_tx_process_test(void *buf, u32 samples, bool iis_32bit)
- {
- static u8 cnt = 0;
- u32 *ptr32 = (u32*)buf;
- u16 *ptr16 = (u16*)buf;
- for (int i = 0; i< samples;i++) {
- if (iis_32bit) {
- ptr32[2*i] = cnt; //16->32位扩展
- ptr32[2*i+1] = cnt;
- } else {
- ptr16[2*i] = cnt; //16->32位扩展
- ptr16[2*i+1] = cnt;
- }
- }
- cnt++;
- #if TRACE_EN
- static u32 ticks = 0;
- static u32 isr_cnt = 0;
- isr_cnt++;
- if (tick_check_expire(ticks,1000)) {
- printk(str_iistx_info,IS_IIS_MASTER(),samples, isr_cnt, samples*isr_cnt);
- isr_cnt = 0;
- ticks = tick_get();
- }
- #endif
- }
- AT(.com_text.iis_code)
- void iis_rx_process_test(void *buf, u32 samples, bool iis_32bit)
- {
- u32 *ptr32 = (u32*)buf;
- u16 *ptr16 = (u16*)buf;
- if (!(iis_mode_cfg_get() & IISCFG_MASTER)) { //slave rx需要进行调速
- aubuf_adjust();
- }
- for (int i = 0; i < samples; i++) {
- if (iis_32bit) {
- dac_put_sample_24bit(ptr32[2*i]>>8, ptr32[2*i+1]>>8);
- } else {
- dac_put_sample_16bit(ptr16[2*i], ptr16[2*i+1]);
- }
- }
- }
- void bsp_iis_test_init(void)
- {
- printf("%s\n",__func__);
- memset(&iis_cfg, 0x00, sizeof(iis_cfg));
- iis_cfg.mode = IIS_MASTER_RAMTX_RAMRX;
- iis_cfg.iomap = IIS_G3;
- iis_cfg.bit_mode = IIS_32BIT;
- iis_cfg.data_mode = IIS_DATA_NORMAL;
- iis_cfg.spr_sel = IIS_SPR_48000;
- iis_cfg.mclk_sel = IIS_MCLK_128FS;
- iis_cfg.mclk_out_en = IIS_MCLK_OUT_DIS;
- if (iis_cfg.mode & IISCFG_DMA) {
- printf("iis_dma config run\n");
- iis_cfg.dma_cfg.samples = IIS_DMA_SAMPLES;
- iis_cfg.dma_cfg.dmabuf_ptr = iis_dmabuf;
- iis_cfg.dma_cfg.dmabuf_len = IIS_DMABUF_LEN;
- iis_cfg.dma_cfg.iis_isr_rx_callbck = iis_rx_process_test; //iis_rx接收完一个DMA后起中断,回调该函数,可以从buf中取出接收到数据
- iis_cfg.dma_cfg.iis_isr_tx_callbck = iis_tx_process_test; //iis_tx发送完一个DMA后起中断,要求向buf中填入数据,以备下一次发送
- }
- dac_aubuf_init();
- dac_spr_set(SPR_48000); //设置采样率
- dac_fade_in(); //dac淡入
- dac_vol_set(0x3000); //首次进入i2s,dac的默认音量, 可填0~0x7fff
- dac_put_zero(256); //初始化256个样点
- iis_cfg_init(&iis_cfg); //初始化iis配置
- iis_start();
- }
- #endif
- #if IIS_RX2SCO_EN
- #define IIS_SCO_DMA_SAMPLES 240
- #define IIS_SCO_DMABUF_LEN (IIS_SCO_DMA_SAMPLES * 4 * 2) //(samples:240)*(sample_len:4)*(dmabuf_switching:2)
- iis_cfg_t iis_sco_cfg AT(.bss.iis.sco);
- u8 iis_sco_dmabuf[IIS_SCO_DMABUF_LEN] AT(.buf.iis.sco);
- struct iis_cvsd_cb_t{
- u8 tmpbuf[240*2];
- u8 wcnt;
- } iis_cvsd_cb AT(.buf.iis.sco);
- AT(.com_text.iis_code)
- void iis_rx_2_sco_process(void *buf, u32 samples, bool iis_32bit)
- {
- u8 *output_buf = NULL;
- u16 *ptr16 = (u16*)buf;
- if ((samples != 240)||(iis_32bit ==1)) { //for only 16bit mode
- return;
- }
- if (!bt_sco_is_msbc() && !bt_sco_dnn_en()) {
- for (int i = 0; i < 120; i++) {
- ptr16[i] = ptr16[4*i];
- }
- memcpy(iis_cvsd_cb.tmpbuf + (iis_cvsd_cb.wcnt++)*120*2, buf, 120*2);
- if (iis_cvsd_cb.wcnt >= 2) {
- iis_cvsd_cb.wcnt = 0;
- output_buf = (u8*)iis_cvsd_cb.tmpbuf;
- }
- } else {
- for (int i = 0; i < 240; i++) {
- ptr16[i] = ptr16[2*i];
- }
- output_buf = (u8*)buf;
- }
- if (output_buf) {
- #if BT_AEC_EN || BT_SCO_SMIC_EN || BT_SCO_DMIC_EN
- bt_aec_process(output_buf, 240, 0);
- #else
- bt_sco_tx_process(output_buf, 240, 0);
- #endif
- }
- }
- void bsp_iis_sco_init(void)
- {
- printf("%s\n",__func__);
- memset(&iis_sco_cfg, 0x00, sizeof(iis_sco_cfg));
- iis_sco_cfg.mode = IIS_MASTER_RAMRX_ONEWIRE;
- iis_sco_cfg.iomap = IIS_G3;
- iis_sco_cfg.bit_mode = IIS_16BIT;
- iis_sco_cfg.data_mode = IIS_DATA_NORMAL;
- iis_sco_cfg.spr_sel = IIS_SPR_16000;
- iis_sco_cfg.mclk_sel = IIS_MCLK_128FS;
- iis_sco_cfg.mclk_out_en = IIS_MCLK_OUT_DIS;
- if (iis_sco_cfg.mode & IISCFG_DMA) {
- iis_sco_cfg.dma_cfg.samples = IIS_SCO_DMA_SAMPLES;
- iis_sco_cfg.dma_cfg.dmabuf_ptr = iis_sco_dmabuf;
- iis_sco_cfg.dma_cfg.dmabuf_len = sizeof(iis_sco_dmabuf);
- iis_sco_cfg.dma_cfg.iis_isr_rx_callbck = iis_rx_2_sco_process;
- iis_sco_cfg.dma_cfg.iis_isr_tx_callbck = NULL;
- }
- iis_cfg_init(&iis_sco_cfg);
- memset(&iis_cvsd_cb, 0x00, sizeof(iis_cvsd_cb));
- }
- #endif
- #endif // I2S_EN
|