Skip to main content
musatoff
Associate II
November 26, 2012
Question

STM32F4 I2S slave Receive with DMA

  • November 26, 2012
  • 4 replies
  • 981 views
Posted on November 26, 2012 at 16:14

Hello!

I try to receive data by I2S3 in slave mode.

First of all I tried to program I2S controller and received data by program polling:

 while(1){

    while( (SPI3->SR & SPI_I2S_FLAG_RXNE) == 0 );

    SPDiffRxBuffer[TimeRXPointer][0] = (long)SPI3->DR;

    if( ++TimeRXPointer >= SPDIFF_BUF_LEN ) TimeRXPointer = 0;

  }

Second, I add function to use DMA

static void I2S_DMA_Init( void )

{

DMA_InitTypeDef DMA_InitStruct;

NVIC_InitTypeDef NVIC_InitStructure;

DMA_DeInit( DMA1_Stream2 );

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);

DMA_InitStruct.DMA_Channel = DMA_Channel_2;

DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&(SPI3->DR);

DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)SPDiffRxBuffer;

DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralToMemory;

DMA_InitStruct.DMA_BufferSize = SPDIFF_BUF_LEN * 4;

DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;

DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;

DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;

DMA_InitStruct.DMA_Priority = DMA_Priority_High;

DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Enable;

DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;

DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_INC4;

DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;

while( DMA_GetCmdStatus( DMA1_Stream2 ) == ENABLE );

DMA_Init( DMA1_Stream2, &DMA_InitStruct );

DMA_ITConfig( DMA1_Stream2, DMA_IT_TC, ENABLE );

DMA_Cmd( DMA1_Stream2, ENABLE );

SPI_I2S_DMACmd( SPI3, SPI_I2S_DMAReq_Rx, ENABLE);

NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream2_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

}

and interrupt funtion

void DMA1_Stream2_IRQHandler( void )

{

  LEDOn( LED1 );

  LEDOff( LED1 );

}

But IRQ not executed and data not filled array SPDiffRxBuffer. Bit RXNE is set and I can read data in polling. But not by DMA. What I write wrong?

Addition: error in RM0090. 

Paragraf: 

27.4.6 I2S slave mode

Point:

Reception sequence

Error text:

The operating mode is the same as for the transmission mode except for the point 1 (refer to

the procedure described in Section 27.4.6: I2S slave mode), where the configuration should

set the 

master reception mode

 using the I2SCFG[1:0] bits in the SPI_I2SCFGR register.

    This topic has been closed for replies.

    4 replies

    Tesla DeLorean
    Guru
    November 26, 2012
    Posted on November 26, 2012 at 17:05

    DMA_InitStruct.DMA_Channel = DMA_Channel_2;

    Isn't SPI3_RX Channel 0? Channel 2 is I2S2_EXT_RX

    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    waclawek.jan
    Super User
    November 26, 2012
    Posted on November 26, 2012 at 17:20

    > Isn't SPI3_RX Channel 0? Channel 2 is I2S2_EXT_RX

    Actually, DMA1 Channel2 Stream2 is I2S*3*_EXT_RX. It was a typo in version 1 of the manual.

    JW

    musatoff
    musatoffAuthor
    Associate II
    November 26, 2012
    Posted on November 26, 2012 at 17:51

    In RM0090 revision 3 is tha I can use or

    DMA1 Channel2 Stream 2

    or

    DMA1 Channel3 Stream0

    for I2S3_EXT_RX. I tried both channels and no get success.

    Tesla DeLorean
    Guru
    November 26, 2012
    Posted on November 26, 2012 at 18:07

    It was a typo in version 1 of the manual.

    Ok, thanks, noted. Rev 3 now posted.
    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..