I am stuck. I have a I2S mono microphone (left channel) which I want to read 32/24 bits from. Clock is up, and scope gives the data I would expect.
But, I only get '0' in my dma rx buffer when my DMA FULL interrupt arrives.
TX works just fine, but I have been fighting with RX for a long time now. I think that part of my problem is that there are no real examples, and those that I can find are for the older chip revision.
If I instead of dma request, let I2S rx generate an interrupt, I can read out data which looks alright (at least not 0) from I2S0_RDR0, so I think it is the DMA setup that I am having issues with.
buf_rx in dma setup is 32-bit aligned.
I2S rx setup:
I2S0_RCR1 = 2; // Water mark
I2S0_RCR2 = I2S_RCR2_SYNC(0) | // Asynch mode
I2S0_RCR3 = 1<<16; // Enable Channel 0
I2S0_RCR4 = I2S_RCR4_FRSZ(I2S_CONFIG_WORDS_IN_A_FRAME-1) |
I2S_RCR4_FSP_MASK | // Frame active low
I2S_RCR4_FSD_MASK; // Frame generated internally. (Output)
I2S0_RCR5 = I2S_RCR5_WNW(31) |
// enable RX
I2S0_RCSR = I2S_RCSR_RE_MASK | // enable rx
I2S_RCSR_BCE_MASK | // enable bit clock
I2S_RCSR_FRDE_MASK; // enable DMA requests
void hal_dma_init_for_i2s_rx(unsigned int buf_rx, unsigned int block_n_sample)
DMAMUX_CHCFG2 = DMAMUX_CHCFG_ENBL_MASK | DMAMUX_CHCFG_SOURCE(14);
DMA_CR |= DMA_CR_EMLM_MASK;
DMA_CSR(2) = DMA_CSR_INTMAJOR_MASK;
tcd.channel = 2;
tcd.nbytes = 4; // Reading from a 32 bit register
tcd.attr = DMA_ATTR_SSIZE(DMA_SIZE_32_BIT) | DMA_ATTR_DSIZE(DMA_SIZE_32_BIT);
tcd.saddr = (unsigned int) &I2S0_RDR0;
tcd.soff = 0; // Do not increment
tcd.slast = 0;
tcd.dadd = buf_rx; // Destination
tcd.doff = 4;
tcd.dlast_sga = 0;
tcd.citer = block_n_sample*2;
tcd.biter = block_n_sample*2;
// enable DMA channel
DMA_SERQ = DMA_SERQ_SERQ(2);