cancel
Showing results for 
Search instead for 
Did you mean: 

Update I2S tx buffer

max23
Associate
Posted on August 17, 2015 at 14:50

Hi!

I set up an STM32F411 to send/receive 8bit µ-law audio samples to/from a WM8974 audio codec via Full-Duplex I2S. Everything works beautifully with hardcoded samples in one big tx buffer (for example a sine wave), but I can't figure out how to update the buffer with fresh samples. I unsuccessfully tried changing the M0AR address of the DMA stream and writing the data to the active buffer in the TC callback. Does anyone have experience with this?

Here is the relevant code:

...

hi2s2.Instance = SPI2;

hi2s2.Init.Mode = I2S_MODE_MASTER_TX;

hi2s2.Init.Standard = I2S_STANDARD_LSB;

hi2s2.Init.DataFormat = I2S_DATAFORMAT_16B;

hi2s2.Init.MCLKOutput = I2S_MCLKOUTPUT_ENABLE;

hi2s2.Init.AudioFreq = I2S_AUDIOFREQ_8K;

hi2s2.Init.CPOL = I2S_CPOL_LOW;

hi2s2.Init.ClockSource = I2S_CLOCK_PLL;

hi2s2.Init.FullDuplexMode = I2S_FULLDUPLEXMODE_ENABLE;

HAL_I2S_Init(&hi2s2);

...

hdma_spi2_tx.Instance = DMA1_Stream4;

hdma_spi2_tx.Init.Channel = DMA_CHANNEL_0;

hdma_spi2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;

hdma_spi2_tx.Init.PeriphInc = DMA_PINC_DISABLE;

hdma_spi2_tx.Init.MemInc = DMA_MINC_ENABLE;

hdma_spi2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;

hdma_spi2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;

hdma_spi2_tx.Init.Mode = DMA_CIRCULAR;

hdma_spi2_tx.Init.Priority = DMA_PRIORITY_HIGH;

hdma_spi2_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;

hdma_spi2_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;

hdma_spi2_tx.Init.MemBurst = DMA_MBURST_SINGLE;

hdma_spi2_tx.Init.PeriphBurst = DMA_PBURST_SINGLE;

HAL_DMA_Init(&hdma_spi2_tx);

__HAL_LINKDMA(hi2s,hdmatx,hdma_spi2_tx);

...

uint8_t rx_buffer[64] = {0};

uint8_t tx_buffer[64] = {

... samples ...

}

...

HAL_I2SEx_TransmitReceive_DMA(&hi2s2, &tx_buffer, &rx_buffer, 64);

Thanks in advance!
2 REPLIES 2
Posted on August 18, 2015 at 08:27

> I unsuccessfully tried changing the M0AR address

You can't do that while the DMA is active and you are not in double-buffer mode. Read DMA_SxM0AR description in the fine manual.

> and writing the data to the active buffer in the TC callback

If you rewrite the buffer content and the output won't change, you don't rewrite the buffer. There's no magic which would retain the output waveform on the output once its source changes.

JW
max23
Associate
Posted on August 18, 2015 at 10:18

Thanks for your reply.

>Read DMA_SxM0AR description in the fine manual.

I read that and I tried disabling DMA, changing the address and enabling it again. Obviously I did something wrong since it didn't work, but that's not the best way to update a circular buffer anyway.

>If you rewrite the buffer content and the output won't change, you don't rewrite the buffer.

I guess so. I have to admit I'm not the most experienced C developer out there and barely even started working with STM32s so that is the main source of the problems I encounter.