AnsweredAssumed Answered

Cannot get I2S RX DMA working on a rev 2 K10 (MK10DX256VMD10)

Question asked by vespaman on Nov 2, 2014
Latest reply on Nov 11, 2014 by Donald Bosley

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

                I2S_RCR2_MSEL(1) |

                I2S_RCR2_DIV(5) |

                I2S_RCR2_BCP_MASK |

                I2S_RCR2_BCD_MASK;

 

    I2S0_RCR3 = 1<<16; // Enable Channel 0

    I2S0_RCR4 = I2S_RCR4_FRSZ(I2S_CONFIG_WORDS_IN_A_FRAME-1) |

                I2S_RCR4_SYWD(31) |

                I2S_RCR4_MF_MASK |

                I2S_RCR4_FSP_MASK |          // Frame active low

                I2S_RCR4_FSD_MASK;           // Frame generated internally. (Output)


    I2S0_RCR5 = I2S_RCR5_WNW(31) |

                I2S_RCR5_W0W(31) |

                I2S_RCR5_FBT(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

 

DMA setup:

void hal_dma_init_for_i2s_rx(unsigned int buf_rx, unsigned int block_n_sample)

{

    DMA_TCD tcd;

 

    DMAMUX_CHCFG2 = DMAMUX_CHCFG_ENBL_MASK | DMAMUX_CHCFG_SOURCE(14);

 

    DMA_CR |= DMA_CR_EMLM_MASK;

    DMA_CSR(2) = DMA_CSR_INTMAJOR_MASK;

    enable_irq(2);

 

    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;

    _dma_init(&tcd);

 

    // enable DMA channel

    DMA_SERQ = DMA_SERQ_SERQ(2);

}


Outcomes