cancel
Showing results for 
Search instead for 
Did you mean: 

DMA & I2S & Full Duplex

andprice
Associate II
Posted on August 13, 2013 at 02:40

Has anyone gotten I2S in full duplex mode on the STM32F405 working?? I just can't seem to get the RX DMA to work. After initializing with the below code the TX DMA IRQs fire and that part works fine but I never get an RX DMA IRQ (Channel 3, stream 3). Any ideas would be appreciated.

/* Initialize I2S GPIOs - follow procedure in stm32f4xx_spi.c
* I2S_SCLK - Port B, Pin 13, I2S_WS - Port B, Pin 12
* I2S_SDO - Port B, Pin 15, I2S_SDI - Port B, Pin 14
* I2S_MCLK - Port C, Pin 6 */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2);
/* There is no I2S2ext defined in stm32f4xx_gpio.h, but according to the
* datasheet (DM00035pdf rev 4 page 62), the I2S2ext interface
* is AF6, NOT AF5 like it is for the rest of the I2S2 pins. */
GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, 0x06);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_SPI2);
/* Initialize the I2S Peripheral */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
RCC_I2SCLKConfig(RCC_I2S2CLKSource_PLLI2S);
RCC_PLLI2SCmd(ENABLE);
while(!RCC_GetFlagStatus(RCC_FLAG_PLLI2SRDY));
I2S_InitStructure.I2S_AudioFreq = SAMPLING_RATE;
I2S_InitStructure.I2S_Standard = I2S_Standard_Phillips;
I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b;
I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;
I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx;
I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Enable;
SPI_I2S_DeInit(SPI2);
I2S_Init(SPI2, &I2S_InitStructure);
I2S_FullDuplexConfig(I2S2ext, &I2S_InitStructure);
SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);
SPI_I2S_DMACmd(I2S2ext, SPI_I2S_DMAReq_Rx, ENABLE);
/* Configure DMA for I2S transactions */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
DMA_Cmd(DMA1_Stream4, DISABLE);
DMA_DeInit(DMA1_Stream4);
DMA_Cmd(DMA1_Stream3, DISABLE);
DMA_DeInit(DMA1_Stream3);
/* Set the parameters to be configured */
DMA_InitStructure_Tx.DMA_Channel = DMA_Channel_0;
DMA_InitStructure_Tx.DMA_PeripheralBaseAddr = 0x4000380C;
DMA_InitStructure_Tx.DMA_Memory0BaseAddr = (uint32_t)&spk_buf[0][0];
DMA_InitStructure_Tx.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStructure_Tx.DMA_BufferSize = (uint32_t)BUFFER_SIZE;
DMA_InitStructure_Tx.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure_Tx.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure_Tx.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure_Tx.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure_Tx.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure_Tx.DMA_Priority = DMA_Priority_High;
DMA_InitStructure_Tx.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure_Tx.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
DMA_InitStructure_Tx.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure_Tx.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_DoubleBufferModeConfig(DMA1_Stream4, (uint32_t)&spk_buf[1][0], 0);
DMA_DoubleBufferModeCmd(DMA1_Stream4, ENABLE);
DMA_Init(DMA1_Stream4, &DMA_InitStructure_Tx);
DMA_InitStructure_Rx.DMA_Channel = DMA_Channel_3;
DMA_InitStructure_Rx.DMA_PeripheralBaseAddr = 0x4000340C;
DMA_InitStructure_Rx.DMA_Memory0BaseAddr = (uint32_t)&mic_buf[0][0];
DMA_InitStructure_Rx.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure_Rx.DMA_BufferSize = (uint32_t)BUFFER_SIZE;
DMA_InitStructure_Rx.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure_Rx.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure_Rx.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure_Rx.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure_Rx.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure_Rx.DMA_Priority = DMA_Priority_High;
DMA_InitStructure_Rx.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure_Rx.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
DMA_InitStructure_Rx.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure_Rx.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_DoubleBufferModeConfig(DMA1_Stream3, (uint32_t)&mic_buf[1][0], 0);
DMA_DoubleBufferModeCmd(DMA1_Stream3, ENABLE);
DMA_Init(DMA1_Stream3, &DMA_InitStructure_Rx);
/* Enable the DMA interrupts and the main NVIC interrupt */
DMA_ITConfig(DMA1_Stream4, DMA_IT_TC, ENABLE);
DMA_ITConfig(DMA1_Stream3, DMA_IT_TC, ENABLE);
NVIC_EnableIRQ(DMA1_Stream4_IRQn);
NVIC_EnableIRQ(DMA1_Stream3_IRQn);
/* Enable DMA Stream and I2S Peripheral */
DMA_Cmd(DMA1_Stream4, ENABLE);
if ((SPI2->I2SCFGR & 0x0400) == 0) {
I2S_Cmd(SPI2, ENABLE);
}
/* Enable DMA Stream and I2S Peripheral */
DMA_Cmd(DMA1_Stream3, ENABLE);
if ((I2S2ext->I2SCFGR & 0x0400) == 0) {
I2S_Cmd(I2S2ext, ENABLE);
}

1 REPLY 1
mkraft
Associate
Posted on November 18, 2013 at 17:30

Hi! Have you managed to solve your problem? Unfortunately I have a very similar one: Reception (DIN) works fine, but on DOUT (I2S2ext on pin PI2) I only can see the 1st bit (MSB) of the word I try to send. It seems that the I2S2ext does work but does not receive an internal clock, hence it is blocked on the 1st bit. The problem persists no matter if I change the pin (e.g. to PB14) or if I run the SPI2 (=I2S2) as master or as slave - always the same result!

ANY HELP IS APPRECIATED!